05. 스트림 활용
#
5.1 필터링- Predicate 필터링
- boolean 반환 함수로
.filter()
적용
- boolean 반환 함수로
- 고유 요소 필터링
.distinct()
로 적용- 고유여부는 hashCode, equals 로 결정
#
5.2 스트림 슬라이싱 (java 9)- 스트림의 요소를 선택하거나 스킵하는 다양한 방법 설명
#
Predicate 이용한 Slicing.takeWhile(Predicate)
- filter 계열
- 순환 중 조건에 만족하지 못하면 그 이후 객체는 순환하지 않음
.dropWhile(Predicate)
- filter 계열
- takeWhile가 반대, 거짓이 되는 지점까지 발견된 요소를 버림
#
스트림 축소.limit(long)
- 중간 연산
- 입력한 수 만큼 요소 개수 제한
#
요소 건너뛰기.skip(long)
- 중간 연산
- 입력한 수 만큼 요소를 생략
#
5.3 매핑#
스트림 각 요소에 함수 적용.map(Function)
- 중간 연산
- 인수로 입력된 Function을 이용해 각 요소를 변환
#
스트림 평면화.flatMap(Function<?, ? extends Stream>)
- 중간 연산
- 인수로 스트림 Function을 받음
- 해당 스트림으로 한 차원 평면화 함
#
5.4 검색과 매칭- 특정 속성이 데이터 집합에 있는 지 여부 검색
#
쇼트 서킷- 전체 스트림을 처리하지 않더라도 결과를 반환할 수 있는 방식
- || 연산이나 && 연산 생각하면 선행 조건에 의해 후의 조건을 판별 안해도 됨을 알 수 있음
#
적어도 한 요소boolean anyMatch(Predicate)
- 쇼트 서킷 최종 연산
- 하나라도 만족하면 true 반환
#
모든 요소와 일치boolean allMatch(Predicate)
- 쇼트 서킷 최종 연산
- 모든 요소가 만족하면 true 반환
boolean noneMatch(Predicate)
- 쇼트 서킷 최종 연산
- 모든 요소가 불만족하면 true 반환
#
요소 검색Optional<T> findAny()
- 쇼트 서킷 최종 연산
- 병렬적으로 실행되었을 때 랜덤으로 찾음
Optional<T> findFirst()
- 쇼트 서킷 최종 연산
- 병렬적으로 실행되도 기존 순서의 첫번째를 찾을 수 있도록 보장
#
5.5 리듀싱Optional<T> redice(BinaryOperator<T>)
T reduce(T, BinaryOperator<T>)
- 최종 연산
- 모든 스트림 요소를 처리해서 값으로 추출
- 함수형에선
fold
라고 부르기도 함 - 내부구현을 이용함으로 병렬성 전환에 대한 이점을 얻을 수 있음
#
내부 상태를 갖는 연산- stateful operation
- 결과를 위해 내부 버퍼가 필요한 연산
- reduce, sum, max 는 내부 상태의 크기가 한정(bounded)되어 있음
- sorted나 distinct 같은 연산은 모든 요소가 버퍼에 추가되어 있어야 함 (비한정)
#
5.7 숫자형 스트림#
기본형 특화 스트림- 스트림 API의 박싱 비용을 피하도록
IntStream
,LongStream
,DoubleStream
을 제공 - 일반 스트림을 변환할 시엔
.mapToInt
와 같은 형태의 중간 연산을 이용 .boxed
로 특화 스트림을 다시 일반 스트림으로 바꿀 수 있음IntStream
,LongStream
에서 숫자 범위 스트림을 생성하는 기능을 가지고 있음IntStream.rangeClosed(1, 100)
:1 <= n <= 100
의 범위를 나타내는 스트림IntStream.range(1, 100)
:1 < n < 100
의 범위
#
5.8 스트림 만들기- 값으로 스트림 만들기
Stream<String> stream = Stream.of("Modern", "Java", "In", "Action));
- 빈 스트림
Stream<String> stream = Stream.empty()
- null이 될 수 있는 객체로 스트림 만들기
- 배열로 스트림 만들기
Arrays.stream(int[])
- 파일로 스트림 만들기
java.nio.file.Files
의 수많은 정적 메서드가 스트림을 반환함
Files.lines 스트림 활용 코드
#
함수로 무한 스트림 만들기iterate
나generate
를 사용해 무한 스트림을 만들 수 있음- 이런 스트림을 unbounded stream 이라고도 함
iterate
Stream.iterate(n -> n + 2)
와 같이 사용- java9 부터는 iterate에
takeWhile
를 제공하는데, 언제까지 실행할지 지정할 수 있음
generate
Stream.generate(Math::random)
과 같이 사용- 인자로
Supplier<T>
를 받음
- 스트림을 병렬로 처리하면서 올바른 결과를 얻으려면
불변 상태 기법
을 고수해야 함 (7장에 자세히 나옴)
#
5.9 마치며- 스트림을 사용하면 복잡한 데이터 처리 질의를 표현 가능
- filter, distinct, skip, limit 메서드로 필터링하거나 자를 수 있음
- 소스가 정렬되어 있을때 dropWhile, takeWhile 용이
- map. flatMap 으로 요소를 추출하거나 변환할 수 있음
- findFirst, findAny로 스트림 요소 검색 가능
- allMatch, noneMatch, anyMatch 로 주어진 Predicate와 일치하는 요소를 스트림에서 검색할 수 있음
- find*, Match 메서드는 쇼트서킷이다
- reduce로 하나의 값을 도출할 수 있음
- 상태 없는 연산 (filter, map 등), 상태 있는 연산 (sorted, distinct 등)
- 기본형 특화 스트림, Int/Double/LongStream
- 컬렉션, 값, 배열, 파일, iterate/generate 메서드로 스트림을 만들 수 있음
- 무한한 개수의 요소를 가진 스트림을 무한 스트림이라 함