람다식(Lambda Expression)
•
함수(메서드)를 간단한 ‘식(expression)’으로 표현하는 방법
•
익명 함수(이름이 없는 함수, anonymous function)
•
함수와 메서드의 차이
◦
근본적으로 동일. 함수는 일반적 용어, 메서드는 객체지향개념 용어
◦
함수는 클래스에 독립적, 메서드는 클래스에 종속적
람다식 작성하기
•
메서드의 이름과 반환타입을 제거하고 ‘→’를 블록{} 앞에 추가한다
•
반환값이 있는 경우 식이나 값만 적고 return문 생략 가능 (끝에 ‘;’ 안 붙임)
•
매개변수의 타입이 추론 가능하면 생략가능(대부분의 경우 생략가능)
람다식 작성 시 주의사항
•
매개변수가 하나인 경우 괄호() 생략가능 (타입이 없을 때만)
•
블록 안의 문장이 하나뿐일 때 괄호 {} 생략가능 (끝에 ‘;’ 안 붙임)
람다식의 예
람다식은 익명 함수? 익명 객체!
•
람다식은 익명 함수가 아니라 익명 객체이다
•
람다식(익명 객체)을 다루기 위한 참조변수가 필요. 참조변수의 타입은?
함수형 인터페이스
•
단 하나의 추상 메서드만 선언된 인터페이스
•
익명 객체를 람다식으로 대체
함수형 인터페이스 타입의 매개변수, 반환타입
•
함수형 인터페이스 타입의 매개변수
•
함수형 인터페이스 타입의 반환타입
java.util.function 패키지
•
자주 사용되는 다양한 함수형 인터페이스를 제공
•
매개변수가 2개인 함수형 인터페이스
•
매개변수의 타입과 반환타입이 일치하는 함수형 인터페이스
Predicate의 결합
•
and(), or(), negate()로 두 Predicate를 하나로 결합(default 메서드)
•
등가비교를 위한 Predicate의 작성에는 isEqual()를 사용 (static 메서드)
함수의 결합
•
f의 반환 타입과 g의 매개변수 타입이 같아야 한다!
•
f.andthen(g);
컬렉션 프레임워크와 함수형 인터페이스
•
함수형 인터페이스를 사용하는 컬렉션 프레임워크의 메서드(와일드 카드 생략)
메서드 참조(method reference) → 클래스이름 :: 메서드이름
•
하나의 메서드만 호출하는 람다식은 ‘메서드 참조'로 간단히 할 수 있다
•
static 메서드 참조
•
생성자와 메서드 참조
•
배열과 메서드 참조
스트림(Stream)
•
다양한 데이터 소스(컬렉션, 배열 등)를 표준화된 방법으로 다루기 위한 것
•
스트림이 제공하는 기능 - 중간 연산과 최종 연산
스트림의 특징
•
스트림은 데이터 소스로부터 데이터를 읽기만할 뿐 변경하지 않는다
•
스트림은 Iterator처럼 일회용이다. (필요하면 다시 스트림을 생성해야 함)
•
최종 연산 전까지 중간연산이 수행되지 않는다 - 지연된 연산
•
스트림은 작업을 내부 반복으로 처리한다
•
스트림의 작업을 병렬로 처리 - 병렬스트림 (멀티스레드)
•
기본형 스트림 - IntStream, LongStream, DoubleStream
◦
오토박싱&언박싱의 비효율이 제거됨(Stream<Integer> 대신 IntStream 사용)
◦
숫자와 관련된 유용한 메서드를 Stream<T>보다 더 많이 제공
스트림 만들기 - 컬렉션
•
Collection 인터페이스의 stream()으로 컬렉션을 스트림으로 변환
스트림 만들기 - 배열
•
객체 배열로부터 스트림 생성하기
•
기본형 배열로부터 스트림 생성하기
스트림 만들기 - 임의의 수
•
난수를 요소로 갖는 스트림 생성하기
•
지정된 범위의 난수를 요소로 갖는 스트림을 생성하는 메서드(Random클래스)
스트림 만들기 - 특정 범위의 정수
•
특정 범위의 정수를 요소로 갖는 스트림 생성하기(IntStream, LongStream)
스트림 만들기 - 람다식 iterate(), generate()
•
람다식을 소스로 하는 스트림 생성하기
•
iterate()는 이전 요소를 seed로 해서 다음 요소를 계산한다
•
generate()는 seed를 사용하지 않는다
스트림 만들기 - 파일과 빈 스트림
•
파일을 소스로 하는 스트림 생성하기
•
비어있는 스트림 생성하기
스트림의 연산
•
스트림이 제공하는 기능 - 중간 연산과 최종 연산
스트림의 연산 - 중간 연산
•
스트림 자르기 - skip(), limit()
•
스트림의 요소 걸러내기 - filter(), distinct()
•
스트림 정렬하기 - sorted()
•
Comparator의 Comparing()으로 정렬 기준을 제공
•
추가 정렬 기준을 제공할 때는 thenComparing()을 사용
•
스트림의 요소 변환하기 - map()
•
스트림의 요소를 소비하지 않고 엿보기 - peek()
•
스트림의 스트림을 스트림으로 변환 - flatMap()
스트림의 연산 - 최종 연산
•
스트림의 모든 요소에 지정된 작업을 수행 - forEach(), forEachOrdered()
•
조건 검사 - allMatch(), anyMatch(), noneMatch()
•
조건에 일치하는 요소 찾기 - fineFirst(), findAny()
•
스트림의 요소를 하나씩 줄여가며 누적연산 수행 - reduce()
Optional<T> (NULL을 간접적으로 다루기 위함)
•
T 타입 객체의 래퍼클래스 - Optional<T>
•
Optional<T> 객체 생성하기
•
Optional<T> 객체의 값 가져오기
OptionalInt, OptionalLong, OptionalDouble
collect()와 Collectors
•
reduce() : 전체에 대한 리듀싱
•
collect() : 그룹별로 나눠서 리듀싱
•
collect()는 Collector를 매개변수로 하는 스트림의 최종 연산
•
Collector는 수집(collect)에 필요한 메서드를 정의해 놓은 인터페이스
•
Collectors 클래스는 다양한 기능의 컬렉터(Collector를 구현한 클래스)를 제공
스트림을 컬렉션, 배열로 변환
•
스트림을 컬렉션으로 변환 - toList(), toSet(), toMap(), toCollection()
•
스트림을 배열로 변환 - toArray()
•
스트림의 통계정보 제공 - counting(), summingInt(), maxBy(), minBy(), ...
•
스트림을 리듀싱 - reducing()
•
문자열 스트림의 요소를 모두 연결 - joining()
스트림의 그룹화와 분할
•
partitioningBy() : 스트림을 2분할한다
•
groupingBy() : 스트림을 n분할한다
스트림의 변환