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 이라고도 함
 
iterateStream.iterate(n -> n + 2)와 같이 사용- java9 부터는 iterate에 
takeWhile를 제공하는데, 언제까지 실행할지 지정할 수 있음 
generateStream.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 메서드로 스트림을 만들 수 있음
 - 무한한 개수의 요소를 가진 스트림을 무한 스트림이라 함