모던 자바인 액션 ch6 - 스트림으로 데이터 수집

김진욱·2022년 9월 29일
0

java

목록 보기
6/13
post-thumbnail

그룹화 - groupingBy

  • 데이터 집합을 하나 이상의 특성으로 분류해서 그룹화하는 연산
Map<Dish.Type, List<Dish>> dishesByType = 
            menu.stream().collect(groupingBy(Dish::getType));

---결과---
{FISH=[prawns, salmon], OTHER=[french fires, rice, season fruit, pizza],
 MEAT=[pork, beef, chicken]}
  • 그룹화된 요소 조작
  • 다수준 그룹화
  • 서브그룹으로 데이터 수집
  • 컬렉터 결과를 다른 형식에 적용하기

분할 - partitioningBy

  • 분할은 분할함수라 불리는 프레디케이트를 분류 함수로 사용하는 특수한 그룹화 기능이다.
Map<Boolean, List<Dish>> partitionedMenu = 
            menu.Stream().collect(partitioningBy(Dish::isVegetarian));

---결과---
{false=[pork, beef, chicken, prawns, salmon],
  true=[frech fries, rice, season fruit, pizza]}
  • 분할의 장점

    • 분할 함수가 반환하는 참, 거짓 두 가지 요소의 스트림 리스트를 모두 유지한다.

Collector 인터페이스

public interface Collector<T, A, R> {
    Supplier<A> supplier();
    BiConsumer<A, T> accumulator();
    Function<A, R> finisher();
    BinaryOperator<A> combiner();
    Set<Charateristics> characteristics();
}
  • T는 수집될 스트림 항목의 제네릭 형식이다.
  • A는 누적자, 즉 수집 과정에서 중간 결과를 누적하는 객체의 형식이다.
  • R은 수집 연산 결과 객체의 형식(대게 컬렉션 형식)이다.

supplier 메서드 : 새로운 결과 컨테이너 만들기

  • supplier 메서드는 빈 결과로 이루어진 Supplier를 반환해야 한다.
public Supplier<List<T>> supplier() {
    return () -> new ArrayList<T>();
}


// 생성자 참조
public Supplier<List<T>> supplier() {
    return ArrayList::new;
}

accumulator 메서드 : 결과 컨테이너에 요소 추가하기

  • accumulator 메서드는 리듀싱 연산을 수행하는 함수를 반환한다.
  • 스트림에서 n번째 요소를 탐색할 때 두 인수(파라미터), 즉 누적자(스트림의 첫 n-1개 항목을 수집한 상태)와 n번째 요소를 함수에 적용한다.
public BiConsumer<List<T>, T> accumulator() {
    return (list, itme) -> list.add(item);
}

// 생성자 참
public BiConsumer<List<T>, T> accumulator() {
    return List::add;
}

finisher 메서드 : 최종 변환값을 결과 컨테이너로 적용하기

  • 스트림 탐색을 끝내고 누적자 객체를 최종 결과로 반환하면서 누적 과정을 끝낼 때 호출할 함수를 반환해야 한다.
public Function<List<T>, List<T>> finisher() {
    return Function.identity();
}

Combiner 메서드 : 두 결과 컨테이너 병합

  • 리듀싱 연산에서 사용할 함수를 반환한다.
  • 스트림의 서로 다른 서브파트를 병렬로 처리할 때 누적자가 이 결과를 어떻게 처리할지 정의한다.
public BinaryOperator<List<T>> combiner() {
    return (list1, list2) -> {
        list1.addAll(list2);
        return list1;
    }
}
  • 분산된 작업의 크기가 너무 작아지면 병렬 수행 속도는 순차 수행 속도보다 느려진다.

Characteristic 메서드

  • Characteristics 메서드는 컬렉터의 연산을 정의하는 Characteristics 형식의 불변 집합을 반환한다.
  • UNORDERED : 리듀싱 결과는 스트림 요소의 방문 순서나 누적 순서에 영향을 받지 않는다.
  • CONCURRENT : 다중 스레드에서 accumulator 함수를 동시에 호출할 수 있으며 이 컬렉터는 스트림의 병렬 리듀싱을 수행할 수 있다. 컬렉터의 플래그에 UNORDERED를 함께 설정하지 않았다면 데이터 소스가 정렬되어 있지 않은 상황에서만 병렬 리듀싱을 수행할 수 있다.
  • IDENTITY_FINISH : finisher 메서드가 반환하는 함수는 단순히 identity를 적용할 뿐이므로 이를 생략할 수 있다. 따라서 리듀싱 과정의 최종 결과로 누적자 객체를 바로 사용할 수 있다. 또한 누적자 A를 결과 R로 안전하게 형변환할 수 있다.

0개의 댓글

관련 채용 정보