Stream API
1. Stream API란
컬렉션, 배열등의 저장 요소를 하나씩 참조하며 함수형 인터페이스(람다식)를 적용한 API
-> 기존의 Iterator, for을 사용하지 않고 처리하며, 직관적이다.
ex) 기존 collection(list)를 조회하기 위한 예시
-iterator의 next() 매소드를 사용 / for문 반복으로 인한 외부 반복 발생
List<String> list = Arrays.asList("a","b","c","d","aa","bb","cc");
//Iterator
Iterator<String> it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//for
for(String temp : list){
System.out.println(temp);
}
**외부반복 : 개발자 코드 -> 컬렉션 -> 개발자코드 -> 컬렉션 -> ..... 과 같이 직접 컬렉션의 요소를 가져옴
**내부반복 : 개발자코드(처리코드 제공) -> 컬렉션에서 내부처리
2. Stream의 특징
1. 원본 데이터 변경 X
2. 일회용 : stream 재사용시 java.lang.IllegalStateException
3. 내부 반복으로 처리(효율적으로 자원처리)
4. 파이프라인 구조 : 생성 -> 가공 -> 결과
예시)
Stream<String> stream = list.stream();
stream.forEach(s -> System.out.println(s));
//stream.forEach(str -> System.out.println(str)); //IllegalStateException 발생
Stream<String> stream2 = list.stream();
long a = list.stream() //생성
.filter(s -> s.startsWith("b")) //가공
.sorted() //가공
.count(); //결과
System.out.println(a);
3. Stream의 옵션
필터링
중간 처리 기능으로 요소를 걸러내는 역할
- distinct() : 중복제거 //.distinct()
- filter() : 조건검색 // 위의 예시 참조
매핑
스트림의 요소를 다른 요소로 대체
- flatMapXXX() : 요소를 대체하는 복수 개의 요소로 구성하는 새로운 스트림을 리턴
- mapXXX() : 요소를 대체하는 요소로 구성하는 새로운 스트림을 리턴
정렬
최종처리 되기전 요소를 정렬
- sorted() : 요소가 객체일 경우 comparable 구현 필수
루핑
요소 전체를 반복
- peek() : 중간 처리 단계, 추가적인 작업을 위해 전체를 루핑 (최종이 될 수 없음)
- forEach() : 최종 처리 단계, 마지막에 최종적으로 요소를 하나씩 처리
매칭
최종 처리단게에서 요소들이 특정 조건을 만족하는 지 확인
- allMatch() : 모든 요소가 만족해야 true
- anyMatch() : 어떤 요소라도 만족하면 true
- noneMatch() : 모든 요소가 만족하지 않는다면 true
기본집계
카운팅, 합계, 평균, 최대값, 최소값들을 산출
- sum(), count(), average(), max(), min()
4. Stream의 병렬처리
멀티코어 CPU 환경에서 하나의 작업을 분할해서 각각의 코어가 병렬적으로 처리하는 것
**데이터 병렬성 : 데이터를 쪼개어
**작업 병렬성 : 작업을 나누어
병렬스트림을 처리하기 위하여 포크조인(ForkJoin) 프레임워크를 사용
- 서브데이터로 나누어 처리하고 최종적으로 결합하여 결과를 만들어낸다.
- parallelStream() : 여러 쓰레드가 요소를 필터링하여 합산하여 최종 처리
- 쓰레드가 너무 많거나 오버헤드 발생 가능 -> 병렬이 항상 좋다고는 할 수 없다.