What is Collectors.collectingAndThen() in Java?
What is the collectors class?
Collectors is a utility class that provides various implementations of reduction operations such as grouping elements, collecting elements to different collections, summarizing elements according to various criteria, etc. The different functionalities in the Collectors class are usually used as the final operations on streams.
The collectingAndThen() method
collectingAndThen() is a static method of the Collectors class that is used to return a Collector that first applies a collector operation and then applies an additional finishing transformation on the result of the collector operation.
The collectingAndThen() method is defined in the Collectors class. The Collectors class is defined in the java.util.stream package. To import the Collectors class, use the following import statement:
import java.util.stream.Collectors;
Syntax
public static <T, A, R, RR> Collector<T, A, RR> collectingAndThen(Collector<T, A, R> downstream, Function<R, RR> finisher)
Parameters
Collector<T, A, R> downstream: The collector to apply.Function<R, RR> finisher: The function to be applied to the final result of the downstream collector.
Return value
The method returns a collector which performs the action of the downstream collector, followed by an additional finishing step.
Code
import java.util.*;import java.util.stream.Collector;import java.util.stream.Collectors;import java.util.stream.Stream;public class Main {static class Person{String name;int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}}public static void main(String[] args) {List<Person> personList = Arrays.asList(new Person("bob", 34), new Person("bob", 43),new Person("mary", 84), new Person("john", 12), new Person("bob", 22));System.out.println("list of person objects - " + personList);Stream<Person> personStream = personList.stream();Map<String, Set<Integer>> result = personStream.collect(Collectors.groupingBy(p -> p.name,Collectors.mapping(e -> e.age,Collectors.collectingAndThen(Collectors.toSet(),Collections::unmodifiableSet))));System.out.println("Result of applying collectingAndThen - " + result);}}
Explanation
- Lines 1-4: We import the relevant packages.
- Lines 8-24: We define a
Personclass withnameandageas the attributes of the class. - Lines 27-28: We create a list of the
Personobjects, calledpersonList, which contains different names and age values. - Line 30: We print the
personList. - Line 32: We create a stream from the
personList. - Lines 34-37: We first apply the
groupingByreduction with the person name as the group by key. We then perform a mapping of the result of thegroupingByoperation to only extract theagevalue from the groupedPersonobjects. We then apply thecollectingAndThenoperation to accumulate the groupedagevalues to a set. But we need an unmodifiable set. Hence, we apply theunmodifiableSet()method of theCollectionsclass on the set created which returns an unmodifiable view of the set created. - Line 39: We print the map of the persons’ names to an unmodifiable set of ages of persons with the same name to the console.