반응형
스트림
- 스트림은 어떤 소스로부터 어떤 스트림을 얻고, 하나 이상의 중간 작업을 수행한 후, 마지막으로 하나의 최종 작업을 수행한다.
- 중간 작업 : filter, map, flatMap, peel, distinct, sorted, limit, substream
- 최종 종료 작업 : forEach, toArray, reduce, collect, min, max, count, anyMatch, allMatch, noneMatch, findFirst, findArray 를 포함한다.
- Java8 부터 추가된 컬렉션의 저장 요소를 하나씩 참조해서 람다식으로 처리할 수 있도록 처리해주는 반복자이다.
- Reduction
- 대량의 데이터를 가공해 축소하는 것
- 데이터의 합계, 평균값, 카운팅, 최댓값, 최소값
- 필터링, 매핑, 정렬, 그룹핑 가능
- 파이프라인
- 여러 개의 스트림이 연결되어 있는 구조
- 파이프라인에서 최종 최종 처리를 제외하고는 모두 중간 처리 스트림으로 본다.
스트림 중간 연산
- Stream<R> map(Function<? super T, ? extends R> mapper) : 입력 T 타입 요소를 1:1 로 R 타입 요소로 변환한 스트림 생성
- Stream<T> filter(Predicate<? super T> predicate) : T타입의 요소를 확인해서 조건을 충족하는 요소만으로 제공하는 새로운 스트림 생성
- Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) : T 타입 요소를 1:N의 R 타입 요소로 변환한 스트림 생성
- Stream<T> peek(Consumer<? super T> action) : T 타입 요소를 사용만 하고, 기존 스트림을 그대로 제공하는 스트림 생성
- Stream<T> skip(long n) : 처음 n개의 요소를 제외한 나머지 요소로 새 스트림 생성
- Stream<T> limit(long maxSize) : maxSize 까지의 요소만 제공하는 스트림 생성 mapToInt(), mapToLong(), maptToDouble()
- Stream<T> sorted() : 정렬된 스트림 생성, T 타입은 Comparable을 구현한 타입
- Stream<T> sorted(Comparator<? super T> comparator) : 정렬된 스트림을 생성, 전체 스트림의 요소를 정렬하기 때문에, 무한 스트림에 적용할 수 없음
- Stream<T> distinct() : 같은 값을 갖는 요소를 제거한 스트림 생성
스트림 최종 연산
- void forEach(Consumer<? super T> consumer) : T 타입의 요소(Element)를 하나씩 처리
- R collect(Collector<? Super T,R> collector) : T 타입의 요소(Element)를 모두 모아 하나의 자료구조나 값으로 변환
- Iterator<T> iterator() : Iterator 객체반환
- Optional<T> max(Comparator<? super T> comparator)
- Optional<T> min(Comparator<? super T> comparator)
- boolean allMatch(Predicate<? super T> predicate)
- boolean anyMatch(Predicate<? super T> predicate)
- boolean noneMatch(Predicate<? super T> predicate)
Stream 요약
- filter, distinct, skip, limit 메서드로 스트림을 필터링 하거나 자를 수 있다.
- map, flatMap 메서드로 스트림의 요소를 추출하거나 변환 할 수 있다.
- findFirst, findAny 메서드로 스트림의 요소를 검색할 수 있다.
- allMatch, noneMatch, anyMatch 메서드를 이용해서 주어진 Predicate와 일치하는요소를 스트림에서 검색할 수 있다.
- reduce 메서드로 스트림의 모든 요소를 반복 조합하며 값을 도출할 수 있다.
- filter, map 등은 상태를 저장하지 않는 상태 없는 연산(stateless operation)이다.
- reduce, sorted, distinct 같은 연산은 값을 계산하는 데 필요한 상태를 저장하므로 상태 있는 연산(stateful operation)이라고 부른다.
- IntStream, DoubleStream, LongStream은 기본형 특화 스트림이다. 이들 연산은 각각 기본형에 맞게 특화 되어 있다.
데이터 리듀싱 요약
- collect는 스트림의 요소를 요약 결과로 누적하는 Collector를 인수로 갖는 최종연산
- 스트림의 요소를 하나의 값으로 reduce 하고 요약하는 Collector 뿐 아니라 최대값, 최소값, 평균값을 계산하는 Collector 등이 미리 정의되어 있다.
- 미리 정의된 groupingBy로 스트림의 요소를 그룹화 할 수 있다.
- 미리 정의된 partitioningBy로 스트림의 요소를 분할 할 수 있다.
- Collector는 다수준의 그룹화, 분할, 리듀싱 연산에 적합하게 설계되어 있다.
- List.of() 로 Collection을 생성하는 경우, ImmutableCollection으로 생성된다.
병렬 스트림
https://java2blog.com/java-8-parallel-stream/
동시성(Concurrency)과 병렬성(Parallelism)
- 이 둘은 멀티 스레드의 동작 방식이라는 점에서는 동일 하지만 서로 다른 목적을 가지고 있다.
- 동시성은 멀티 작업을 위해 멀티 스레드가 번갈아 가면서 실행하는 성질
- 병렬성은 멀티 작업을 위해 멀티 코어를 이용해서 동시에 실행하는 성질
- 싱글 코어 CPU를 이용한 멀티 작업은 병렬적으로 실행 되는 것처럼 보이지만, 사실은 번갈아 가면 실행 하는 동시성 작업
데이터 병렬성 : 전체 데이터를 쪼개어 서브 데이터들로 만들고, 이 서브 데이터들을 병렬 처리해서 작업을 빨리 끝내는 것
작업 별렬성 : 서로 다른 작업을 병렬 처리하는 것
포크조인(ForkJoin) 프레임워크
- 포크 단계 단계에서는 전체 데이터를 서브 데이터로 분리 후 서브 데이터를 멀티 코어에서 병렬로 처리
- 조인 단계에서는 서브 결과를 결합해서 최종 결과를 생산
병렬 스트림 생성 메서드
- 병렬 처리를 위해 코드에서 포크조인 프레임워크를 직접 사용할 수는 있지만, 병렬 스트림을 이용할 경우에는 백그라운드에서 포크조인 프레임워크가 사용되기 때문에 매우 쉽게 병렬 처리 할 수 있음
- parallelStream() 메서드는 컬렉션으로 부터 병렬 처리 스트림을 바로 리턴 합니다.
- parallel() 메서드는 순차 처리 스트림을 병렬 스트림으로 변환해서 리턴 합니다.
- 내부적으로 전체요소를 서브 요소들로 나누고, 이 서브 요소들을 개별 스레드가 처리합니다.
- 서브 처리 결과가 나오면 결합해서 마지막 최종 처리 결과를 리턴 합니다.
병렬 스트림 주의사항
- 병렬스트림은 항상 순차스트림 보다 빠르지 않으니 확인이 필요하다.
- 박싱(Boxing)을 주의하자. 오토박싱과 언박싱 과정은 성능을 크게 저하시킨다. (자바에서 제공하는 기본형 특화 스트림을 사용하는 것이 좋다.)
- 순차스트림 보다 병렬스트림에서 성능이 떨어지는 연산이 존재한다. limit나 findFirst 처럼 요소의 순서에 의존하는 연산을 병렬 스트림에서 수행하려면 비싼 비용이 필요하다.
- 소량의 데이터라면 병렬 스트림이 도움이 되지는 않는다.
- 소량의 데이터를 처리하는 과정은 병렬화 과정에서 생기는 부가비용을 상쇄할 수 있을 만큼 이득을 얻지 못하기 때문이다.
- 스트림을 구성하는 자료구조가 적절한지 확인하여라. (ArrayList는 LinkedList 보다 효율적으로 분리가 가능하다.)
- 스트림의 특성과 파이프라인의 중간 연산이 스트림의 특성을 어떻게 바꾸느냐에 따라서 분해 과정의 성능이 달라질 수 있다.
- 필터 연산이 있을 경우 크기를 예측할 수 없으므로 효과적인 스트림 처리가 되지 않는다.
- 최종 연산 과정에서 병합비용을 살펴보아야 한다. (병합 비용이 비싸다면 병렬 스트림으로 얻은 성능의 이익이 서브스트림의 부분 결과를 합치는 과정에서 상쇄될 수 있다.)
날짜와 시간 API
자바 7 이전의 날짜와 시간 API
- 쓰레드에서 안전하지 않음
- 사용하기 불편 – Date, Calendar
- 일관성이 떨어짐 – 애매한 unix time 추상화
- 불규칙한 성능
- 오픈 소스 joda-time을 거의 표준으로 사용(사용하기 간편)
이후 자바 8에서는 공식적으로 지원
반응형
'BE > Java' 카테고리의 다른 글
[BAEKJOON] 18405번 : 경쟁적 전염 (JAVA) (1) | 2024.06.09 |
---|---|
[JMeter] JMeter 사용 및 설치 방법 (0) | 2024.05.06 |
[Java 8] 람다식과 함수형 인터페이스 (0) | 2024.03.10 |
[Java] Reflection? (0) | 2023.12.25 |
[Java] Jacoco 간단하게 사용해보기 (Maven) (0) | 2023.07.08 |