ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스트림으로 데이터 수집
    Java/모던자바인액션요약 2022. 8. 23. 00:01
    728x90

    개요

    만약 통화별로 트랜잭션을 그룹화하기 위해서 코드를 작성하려면 어떻게 해야 할까요?

    Map<Currency, List<Transaction>> transactionByCurrencies = new HashMap<>();
    
    //트렌젝션 리스트에서 하나씩 꺼내옴
    for(Transaction transaction : transactions){
    	Currency currency = transaction.getCurretncy();
    	List<Transaction> transactionForCurrency = transactionByCurrencies.get(currency);
    	if(transactionForCurrency == null){
    		transactionForCurrency = new ArrayList<>();
    		transactionByCurrencies.put(currency, transactionForCurrency);
    	}
    	transactionForCurrency.add(transaction);
    }

    '통화별로 트랜잭션 리스트를 그룹화하시오' 라고 간단히 표현할 수 있지만 코드가 무엇을 실행하는지 한눈에 파악하기 힘듭니다.

     

    Stream에 toList를 사용하는 대신 더 범용적인 컬렉션 파라미터를 collect 메서드에 전달함으로써 원하는 연산을 훨씬 간결하게 구할 수 있습니다.

    Map<Currency, List<Transaction>> transactionByCurrencies = 
    transactions.stream().collect(groupingBy(Transaction::getCurrency));

     

    훨씬 간단해진 모습을 볼 수 있습니다.

     

    컬렉터란 무엇인가?

    이전 예제에서 collect 메서드로 Collector 인터페이스 구현체를 전달했습니다.

    '각 요소를 리스트로 만들어라'를 의미하는 toList를 사용했습니다.

     

    컬렉터는 리듀싱 연산을 이용해서 스트림의 각 요소를 방문하며 컬렉터가 작업을 처리합니다.

     

    위의 예시인 groupingBy 같은 컬렉터 인터페이스 구현체를 사용하면 각 트렌젝션에서 통화를 추출한 다음에 통화를 키로 사용해서 트랜젝션 자체를 결과 맵에 누적시킵니다.

     

    보통 구현되어 있는 컬렉터들은 크게 세 가지로 구분할 수 있습니다.

    - 스트림 요소를 하나의 값으로 리듀스 하고 요약

    - 요소 그룹화

    - 요소 분할

     

    제공되는 컬렉터들 기능 요약

    counting()

    개수를 측정

     

    maxBy(), minBy()

    인자로 Comparator가 들어가며 최대/최소 값을 계산할 수 있습니다.

     

    summingInt()

    인자로 객체를 int로 매핑하는 함수를 받아 값의 합을 계산할 수 있습니다.

    유사한 메서드로 summingDouble, summingLong이 있습니다.

     

    이외에도 averagingInt, averagingDouble, averagingLong, summarzingInt 등의 메서드들이 있습니다.

     

    joining()

    인자를 넣어서 두 요소 사이에 구분 문자열을 넣을 수도 있습니다.

    내부적으로 StringBuilder를 이용해서 문자열을 하나로 만들어줍니다.

     

    reducing()

    위의 모든 켈렉터들은 reducing 팩토리 메서드로 구현할 수 있습니다.

    그럼에도 위의 컬렉터들을 소개한 이유는 프로그래밍적으로 편의성, 가독성이 증가하기 때문입니다.

     

    groupingBy()

    인자로 분류함수를 넣어주어야 합니다.

    쉽게 그룹핑 할 수 있습니다.

    각 키에 대응하는 스트림의 모든 항목을 리스트를 값으로 갖는 맵이 반환됩니다.

     

    partitioningBy()

    인자로 Boolean을 반환하는 분할 함수를 넣어주어야 합니다.

    쉽게 분할할 수 있습니다.

    최대 두 개의 그룹으로 분류됩니다(참 or 거짓)

     

     

    Collector 인터페이스 직접 구현하기

    public interface Collector<T, A, R>{
    	Supplier<A> supplier();
    	BiConsumer<A, T> accumulator();
    	Function<A, R> finisher();
    	BinaryOperator<A> combiner();
    	Set<Characteristics> characteristics();
    }

     

    다섯 가지 메서드를 직접 구현하여 자신만의 커스텀 컬렉터를 만들 수 있습니다.

     

    직접 커스텀한 컬렉터를 구현할 수 있으며 이를 통해 성능 향상도 노려볼 수 있습니다.

     

    개인적으로 아직 잘 와닿지 않는 부분이라 디테일하게 읽고 정리하진 않았습니다.

    'Java > 모던자바인액션요약' 카테고리의 다른 글

    컬렉션 API 개선  (0) 2022.09.06
    병렬 데이터 처리와 성능  (0) 2022.08.29
    스트림 활용  (0) 2022.08.18
    스트림 소개  (0) 2022.08.15
    람다 표현식  (0) 2022.08.10

    댓글

Designed by Tistory.