[Java] 스트림 최종 처리 - 요소 수집 collect()

Bam·2024년 3월 20일
0

Java

목록 보기
85/98
post-thumbnail

요소 수집

스트림은 필터링, 매핑한 요소들을 수집하는 최종 처리 메소드 collect()를 지원하고 있습니다. collect()는 단순한 요소 수집과 그룹화(그룹핑)한 후 Map 객체를 만드는 기능을 제공하고 있습니다.

요소 수집

collect(Collector<T, A, R> collector)는 필터링, 매핑된 요소들을 새로운 컬렉션(List, Set, Map)에 수집하고 컬렉션을 반환하는 메소드입니다.

매개변수인 Collector는 수집한 요소를 담을 컬렉션을 지정합니다. <T, A, R>에서 T는 요소, A는 누적기, R은 컬렉션을 의미하며 T를 A가 R에 저장한다라는 의미입니다.

구현 객체 collectorCollectors 클래스의 정적 메소드로 취득할 수 있습니다. toList()를 사용하면 ListtoSet()SettoMap()Map 컬렉션에 저장합니다.

public class Main {
    public static void main(String[] args) {
        List<Integer> intList = new ArrayList<>();
        intList.add(1);
        intList.add(2);
        intList.add(3);
        intList.add(4);
        intList.add(5);

        Stream<Integer> stream = intList.stream();
        List<Integer> oddList = stream.filter(elem -> elem % 2 == 1)
                .collect(Collectors.toList());

        for (int elem: oddList) {
            System.out.print(elem + " ");
        }
    }
}

추가적으로 Java 16이후에선 toList()를 간결하게 작성할 수 있습니다.

//이전 버전
List<Integer> oddList = stream.filter(elem -> elem % 2 == 1)
                .collect(Collectors.toList());
      
//Java 16 이후
List<Integer> oddList = stream.filter(elem -> elem % 2 == 1).toList();

요소 그룹핑

collect()는 요소 수집 외에도 컬렉션의 요소를 그룹핑해서 Map 객체를 생성하기도 합니다.

그룹핑은 공통적인 요소를 모아서 그룹화하는 것을 말합니다.

그룹핑으로 Map 객체를 생성하기 위해서는 groupingBy() 메소드를 사용합니다.

메소드설명
groupingBy(Function<T, K>)컬렉션 요소 그룹핑

이 메소드에서는 TK로 매핑하고, 이 K를 키로 가지고 List<T>를 값으로 갖는 Map 객체를 생성합니다.

다음 코드는 멤버를 그룹핑하는 예제입니다. 이때 성별 정보를 키로 이용하고 List<Memeber>를 값으로 갖는 Map 객체를 생성합니다.

public class Main {
    public static void main(String[] args) {
        List<Member> list = new ArrayList<Member>();
        list.add(new Member("김커피", "남자"));
        list.add(new Member("박콜라", "여자"));
        list.add(new Member("이녹차", "여자"));
        list.add(new Member("최홍차", "남자"));
        list.add(new Member("윤우유", "여자"));

        Map<String, List<Member>> map = list.stream()
                .collect(Collectors.groupingBy(elem -> elem.getGender()));

        List<Member> maleMemberList = map.get("남자");
        maleMemberList.stream().forEach(elem -> System.out.print(elem.getName() + " "));

        System.out.println();

        List<Member> femaleMemberList = map.get("여자");
        femaleMemberList.stream().forEach(elem -> System.out.print(elem.getName() + " "));
    }
}

추가적으로 groupBy() 메소드는 그룹핑 이후 집계에 대한 기능을 수행하기 위해 두 번째 매개변수로 Collectors를 사용할 수 있게 설계되어 있습니다. 다음 메소드들을 두 번째 매개변수로 이용할 수 있습니다.

메소드설명
mapping(Function, Colllector)매핑
averagingDouble(ToDoubleFunction)평균값 취득
maxBy(Comparator) minBy(Comparator)최대값, 최소값 취득
counting()요소 수 취득
reducing(BinaryOperator<T>)커스텀 집계

다음 코드는 위와같이 남자와 여자를 키로해서 만든 맵의 요소 수를 취득하는 코드입니다.

public class Main {
    public static void main(String[] args) {
        List<Member> list = new ArrayList<Member>();
        list.add(new Member("김커피", "남자"));
        list.add(new Member("박콜라", "여자"));
        list.add(new Member("이녹차", "여자"));
        list.add(new Member("최홍차", "남자"));
        list.add(new Member("윤우유", "여자"));

        Map<String, Long> map = list.stream()
                .collect(Collectors.groupingBy(
                        elem -> elem.getGender(),
                        Collectors.counting()
                ));

        System.out.println(map);
    }
}

0개의 댓글