람다식
- 익명함수
- 함수의 구성을 (매개변수 목록) -> {실행문} 으로 간단하게 한 것
- 한번 쓰이고 말 함수를 람다식으로 선언하면 코드를 간결하게 할 수 있다.
- 람다식에서 주의해야할 것 (출처 : https://mine-it-record.tistory.com/476)
- 메서드이름과 반환타입의 경우에는 생략할 수 있다. (대부분 생략한다.)
- 매개변수의 타입을 추론할 수 있는 경우에는 타입을 생략할 수 있다. (대부분 생략이 가능하다.)
- 매개변수가 하나인 경우에는 괄호( )를 생략할 수 있다.
- 함수의 몸체가 하나의 명령문만으로 이루어진 경우에는 중괄호{ }를 생략할 수 있다. (이때 세미콜론은 붙이지 않음)
- 함수의 몸체가 하나의 return 문으로만 이루어진 경우에는 중괄호{ }를 생략할 수 없다.
- return문 대신 표현식을 사용할 수 있으며, 이때 반환값은 표현식의 결괏값이 된다. (이때 세미콜론은 붙이지 않음)
- => 람다식의 바디가 여러줄로 된 경우 & return이 있는 경우엔 중괄호와 세미콜론을 생략할 수 없다.
Stream
- 스트림은 배열이나 컬렉션 프레임워크의 원소에 쉽게 접근하기 위해 사용함
e.g. 더 이상 for( int i ; i < array.size() ; i++ )를 하지 않아도 모든 원소에 접근할 수 있음 -> 코드가 훨씬 간결해짐 - 스트림 사용 방법은 1. Stream 생성 2. 중개 연산 3. 최종 연산으로 나누어짐
이 세가지를 한번에 사용하면 아래와 같음
데이터소스객체.Stream생성().중개연산().최종연산(); - 스트림 생성
배열 스트림 : Stream stream = _Arrays.stream(arr);_
컬렉션 스트림 : Stream stream = arrList.stream( );
Stream 메소드 사용 : Stream.builder( ) / Stream.generate( ) / Stream.iterate( )
e.g. Stream stream = Stream.builder( ).add(1),add(2),add(3).build( );
e.g. Stream stream = Stream.generate(() -> "gen").limit(5); // [gen, gen, gen, gen, gen] // limit없으면 크기 무한
e.g. Stream stream = Stream.iterate(30, n -> n + 2).limit(5); // [30, 32, 34, 36, 38] // limit없으면 크기 무한
기본 스트링 : 기본형을 저장하는 스트링 (Int / Double / Long이 있다)
e.g. IntStream stream = IntStream.range(1,3); // [1,2,3] - 중개 연산
필터링 : filter( ) 내부의 조건을 만족하는 요소들 추출
e.g. IntStream intStream = new IntStream(1,10).filter(n -> n%2 == 0);
매핑 : map( ) 내부의 연산을 모든 요소별로 수행하고 원본 값에 대입
e.g. IntStream intStream = new IntStream(1,10).map(n -> n+1);
중개연산 안에 모두 람다식이 사용되는데
람다식의 매개변수로 사용되는 것은 각 요소를 의미한다. - 최종 연산
산술 연산 : sum( ), average( ), min( ), max( )
형변환 : getAsInt( ), getAsDouble( ) 등
- forEach( ) : 스트림의 모든 요소에 접근하여 괄호 안의 작업을 수행
e.g. Arrays.asList(1,2,3,4).stream().forEach(System.out::println);
e.g. Arrays.asList(1,2,3,4).stream().forEach(n -> System.out.println(n)); - findAny( ) / findFirst( ): 반드시 filter의 뒤에 쓰이며, filter의 조건을 만족하는 객체를 Optoinal 형태로 반환
조건에 일치하는 요소가 없다면 empty가 리턴된다.
- findFirst()는 Stream의 순서를 고려하여 가장 앞에 있는 요소를 리턴
- findAny()는 스트림을 처리하면서 가장 먼저 찾은 요소를 리턴 (멀티 쓰레드 상황에서는 리턴값이 매번 달라질 수도 있다)
- forEach( ) : 스트림의 모든 요소에 접근하여 괄호 안의 작업을 수행
cf. 컴퓨터에서 스트림은 '연속적인 데이터의 흐름'을 뜻한다. 혼공자에서 배온 read( )와 wrtie( )를 할 수 있는 스트림도 그런 의미로 사용되었다. 하지만 컬렉션 프레임워크에 적용되는 스트림은 이와는 다른 것이므로 구분을 해두자!
전자는 java.io.InputStream || java.io.OutputStream 이고, 후자는 java.util.stream이다.
Optional
- NPE(null pointer error)를 방지할 수 있게 Java8부터 도입된 문법
- Optional은 null이 올 수 있는 값을 감싸는 Wrapper 클래스
전까지는 if(object == null) {Debug.Log("객체가 비어있습니다");} 처럼
null 이 있을 상황을 대비해서 if로 따로 처리를 해줬어야 했는데, 그럴 필요가 없어짐 - [Optional 사용법]
선언 : 타입을 Optional<T> 로 선언해서 사용하면 된다.
초기화 :
① Optional.of(value) : value에 있는 값이 null인 경우 NPE가 발생
② Optional.ofNullable(value) : value가 null이면 Optional.empty 객체가 리턴된다.
이후 orElse 또는 orElseGet 메소드를 이용해 값이 없는 경우에 리턴할 객체를 설정하여 안전하게 값을 가져올 수 있다.
ex. String name = optional.orElse("anonymous"); // 값이 없다면 "anonymous" 를 리턴
③ Optional.empty( ) : Optional.empty 객체가 리턴된다.
이때 Optional.empty는 Optional 클래스에 static으로 선언되어있다.
따라서 새로운 객체를 생성하는게 아니라, 모든 객체가 공유하게 되어 메모리를 아끼고 있다.
// Stream.filter.findAny로 값이 있는지 확인하는 코드를 짜고 싶은데 Optional의 세계가 너무 깊은 것 같아서 지금 단계에서는 pass!
// 당분간은 contains( )함수만 사용해야할 것 같다.
참고 : Optional 제대로 활용하기 - Increment (latera.kr)
'JAVA' 카테고리의 다른 글
[JAVA] equals로 문자열 비교할 때 NullPointerException 피하는 방법 (0) | 2023.05.22 |
---|---|
[WIL] 5/08~5/14 컬렉션 프레임 워크 (0) | 2023.05.14 |
스프링 빈과 자동 의존관계 설정 (0) | 2023.04.03 |
[스프링 입문] 회원관리 예제 - 도메인, 레포지토리, 서비스 (0) | 2023.03.14 |
[스프링 입문] 화면 띄우기 (1) | 2023.03.07 |