스트림과 병렬 처리
스트림
람다식으로 요소 처리 코드 제공
- Stream이 제공하는 대부분의 요소 처리 메소드는 함수적 인터페이스 매개 타입을 가지기 때문에 람다식 또는 메소드 참조를 이용해서 요소 처리 내용 매개값으로 전달
내부 반복자 사용으로 병렬 처리 쉬움
- 외부 반복자 : 개발자가 코드로 직접 컬렉션의 요소를 반복해서 가져오는 코드 패턴 ⇒ for문, while…
- 내부 반복자 : 컬렉션 내부에서 요소들을 반복시키고, 개발자는 요소당 처리해야 할 코드만 제공하는 코드 패턴
- 이점
- 개발자는 요소 처리 코드에만 집중
- 멀티 코어 CPU 최대한 활용 ⇒ 하나씩 처리하는 순차적 외부 반복자보다 효율적
- 코드 간결
- 요소의 병렬 처리가 컬렉션 내부에서 처리
중간 처리와 최종 처리
- 중간 처리 ⇒ 매핑, 필터링, 정렬
- 최종 처리 ⇒ 반복, 카운팅, 평균, 총합 등의 집계 처리
스트림 종류
- BaseStream 인터페이스를 부모로 해서 4개 자식 인터페이스
- Stream ⇒ 객체 요소 처리
- IntStream ⇒ int 요소
- LongStream ⇒ long 요소
- DoubleStream ⇒ double 요소
스트림 파이프라인
- 리덕션 : 대량의 데이터를 가공해서 축소하는 것 ⇒ 데이터의 합계, 평균값, 카운팅, 최대값
- 컬렉션 요소를 리덕션 결과물로 바로 집계할 수 었을 경우 중간 처리
중간 처리, 최종 처리
- 중간 처리, 최종 처리 파이프라인으로 해결
- 최종 처리를 제외하고는 모두 중간 처리 스트림
- 최종 처리가 시작되기 전까지 중간 처리 지연
중간 처리 메소드
최종 처리 메소드
필터링
- distinct() : 중복 제거
- filter() : 조건 필터링
- 모든 스트림이 가지고 있는 공통 메소드
매핑
- flatMap() 메소드
- 모든 요소를 대체하는 복수 개의 요소들로 구성된 새로운 스트림 리턴
- map() 메소드
- 요소를 대체하는 요소로 구성된 새로운 스트림 리턴
- asDoubleStream(), asLongStrean(), boxed() 메소드
- double, Long 요소로 타입 변환해서 스트림 생성
- Integer, Long, Double 요소로 박싱해서 스트림 생성
정렬(sorted())
- 중간 단계에서 요소를 정렬해 최종 처리 순서 변경
- 객체 요소일 경우 클래스가 Comparable 구현하지 않으면 ClassCastException 에러 발생
- 객체 요소가 Comparable 구현하지 않았다면 Comparator 매개값으로 갖는 sorted() 메소드 사용
루핑(peek(), forEach())
- 요소 전체를 반복하는 것
- peek() : 중간 처리 메소드 ⇒ 최종 메소드 호출해야 동작
- forEach() : 최종 처리 메소드 ⇒ 이후에 다른 최종 메소드 호출하면 안됨
매칭(allMatch(), anyMatch(), noneMatch())
- 최종 처리 단계에서 요소들이 특정 조건에 만족하는지 조사
- allMatch() : 모든 요소들이 매개값으로 주어진 Predicate 의 조건 만족하는지 조사
- anyMatch() : 최소한 한 개의 요소가 매개값으로 주어진 Predicate 조건 만족하는지 조사
- noneMatch() : 모든 요소들이 매개값으로 주어진 Predicate의 조건을 만족하지 않는지 조사
기본 집계(sum, count, average, max, min)
- 최종 처리 기능
- 대량의 데이터를 가공해서 축소하는 리덕션
optional 클래스
- Optional, OptionalDouble, OptionalInt, OptionalLong
- 저장하는 값의 타입만 다를 뿐 제공하는 기능은 거의 동일
- 단순히 집계만 저장하는 것이 아니라, 집계 값이 존재하지 않을 경우 디폴트 값을 설정할 수 있고, 집계 값을 처리하는 Consumer 등록 가능
커스텀 집계(reduce)
- 프로그램화 해서 다양한 집계 결과물 만들 수 있음
- 스트림에 요소가 전혀 없을 경우 디폴트 값인 identity 매개값 리턴
수집(collect)
- 필요한 요소만 컬렉션에 담을 수 있고, 요소들을 그룹핑한 후 집계 가능
- 필터링한 요소 수집
- 어떤 요소를 어떤 컬렉션에 수집할 것인지 결정
- 사용자 정의 컨테이너에 수집
- 요소를 그룹핑해서 수집
- 그룹핑 후 매핑 및 집계
병렬 처리
- 프코조인 프레임워크
- 병렬 스트림의 병렬 처리
- 포크 단계에서 전체 데이터를 서브 데이터로 분리 ⇒ 서브 데이터를 멀티 코어에서 병렬로 처리 ⇒ 조인 단계에서 서브 결과를 결합해 최종 결과 만들어 냄
- 병렬 스트림 생성
- 백그라운드에서 포크조인 프레임워크 사용됨 ⇒ 개발자는 매우 쉽게 병렬 처리 가능
- parallelStream(), parallel()