스트림은 필터링, 매핑한 요소들을 수집하는 최종 처리 메소드 collect()
를 지원하고 있습니다. collect()
는 단순한 요소 수집과 그룹화(그룹핑)한 후 Map 객체를 만드는 기능을 제공하고 있습니다.
collect(Collector<T, A, R> collector)
는 필터링, 매핑된 요소들을 새로운 컬렉션(List, Set, Map)에 수집하고 컬렉션을 반환하는 메소드입니다.
매개변수인 Collector
는 수집한 요소를 담을 컬렉션을 지정합니다. <T, A, R>
에서 T
는 요소, A
는 누적기, R
은 컬렉션을 의미하며 T를 A가 R에 저장한다라는 의미입니다.
구현 객체 collector
는 Collectors
클래스의 정적 메소드로 취득할 수 있습니다. toList()
를 사용하면 List
를 toSet()
은 Set
을 toMap()
은 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>) | 컬렉션 요소 그룹핑 |
이 메소드에서는 T
를 K
로 매핑하고, 이 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);
}
}