- 스트림이란
- 외부 반복하는 컬렉션과 달리 내부 반복을 수행한다.
- 재사용 가능한 컬렉션과 달리 한 번만 사용할 수 있다.
- 원본 데이터를 변경하지 않는다.
- 필터-맵 API 연산 사용으로 인한 지연 연산으로 성능 최적화
- parallelStream()으로 병렬 처리 지원
- 스트림 동작 흐름
- 스트림의 생성
- 스트림의 중개 연산 (스트림의 변환) 필터나 맵
- 스트림 필터링 : filter(), distinct()
- filter: stream2**.**filter(n **->**n % 2 **!=**0) - 홀수만 골라낸다.
- distinct: 중복 요소 제거
- 스트림 변환 : map(), flatMap()
- map: 스트림의 요소를 인수로 전달해 새 스트림을 반환한다.
- flatmap: 여러 문자열이 있다면 분리할 수 있다.
- 스트림 제한 : limit(), skip()
- limit: 첫 요소부터 전달된 개수만큼만의 요소만 반환
- skip: 첫 요소부터 전달된 개수만큼 제외한 나머지 요소 반환
- 스트림 정렬 : sorted()
- sorted: 정렬 수행 내부 파라미터로 Comparator.*reverseOrder*()
- 스트림 연산 결과 확인 : peek()
- 스트림 필터링 : filter(), distinct()
- 스트림의 최종 연산 (스트림의 사용)
- 요소의 출력 : forEach() - 각 요소를 출력하는 용도
- 요소의 소모 : reduce()
- 요소의 검색 : findFirst(), findAny()
- 직렬 처리엔 같은 기능을 한다.
- 병렬 처리시
- findFirst() - stream의 순서를 고려해 가장 앞에 있는 요소 리턴
- findAny() - 가장 먼저 찾은 요소 리턴 따라서 뒤쪽 요소가 리턴될 수 있다. 값이 달라질 수 있다.
- 요소의 검사 : anyMatch(), allMatch(), noneMatch()
- anyMatch() - 일부 요소가 조건 만족할때 true
- allMatch() - 모든 요소가 조건을 만족할때 true
- noneMatch() - 모든 요소가 조건을 만족하지 않을때 true
- 요소의 통계 : count(), min(), max()
- count() - 개수
- 요소의 연산 : sum(), average()
- 요소의 수집 : collect()
- 스트림 병렬 처리 관리
- 스트림은 람다식을 사용, 별도 스레드에서 병렬 처리를 관리한다.
- 외부 지역 변수를 참조할땐 final한 변수를 복사해 가져간다. 왜
- 스택 영역에 지역 변수를 가지고 있으며 람다식은 별도의 스레드를 가지기에 다른 스레드의 스택 영영에 대한 지역 변수 참조가 불가능하다.
- 메서드 영역
- 힙 영역
- JVM 스택 영역JVM의 메모리 구조는 세 가지이다.
- 그러나 스택 영역은 스레드 간 공유가 불가능하다.
- 스택 영역에 지역 변수를 가지고 있으며 람다식은 별도의 스레드를 가지기에 다른 스레드의 스택 영영에 대한 지역 변수 참조가 불가능하다.
- ParallelStream(), parallel()
- 사용만으로 스트림을 병렬 처리할 수 있다.
- 순서 보장 X
- 컬렉션 사이즈 작을땐 오히려 성능이 안 나올 수 있다.
- 분할 및 병합 과정 비용, 멀티 스레드 환경에 대한 컨텍스트 스위칭 비용 등을 고려해야 한다.
[참고 자료]
댓글