Java Stream collect() performs a mutable reduction operation on the elements of the stream. This is a terminal operation.
A mutable reduction operation process the stream elements and then accumulate it into a mutable result container. Once the elements are processed, a combining function merges all the result containers to create the result.
There are two variants of Java Stream collect() method.
The Collector is an interface that provides a wrapper for the supplier, accumulator, and combiner objects. The second method is useful when we are utilizing the Collectors class to provide built-in Collector implementation. The three parameters of the collect() function are:
Let’s look at some examples of Stream.collect() method.
Let’s say you want to concatenate the list of strings to create a new string. We can use Stream collect() function to perform a mutable reduction operation and concatenate the list elements.
List<String> vowels = List.of("a", "e", "i", "o", "u");
// sequential stream - nothing to combine
StringBuilder result = vowels.stream().collect(StringBuilder::new, (x, y) -> x.append(y),
(a, b) -> a.append(",").append(b));
System.out.println(result.toString());
// parallel stream - combiner is combining partial results
StringBuilder result1 = vowels.parallelStream().collect(StringBuilder::new, (x, y) -> x.append(y),
(a, b) -> a.append(",").append(b));
System.out.println(result1.toString());
Output:
aeiou
a,e,i,o,u
If you want to concatenate the list of strings, we can use the method references to reduce the code size.
String result2 = vowels.parallelStream()
.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
.toString();
The Collectors class provides many useful implementations of the Collector interface. Let’s look at an example where we will filter the list of integers to select only even integers. Stream filter() is an intermediate operation and returns a stream. So, we will use the collect() function to create the list from this stream.
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);
List<Integer> evenNumbers = numbers.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
System.out.println(evenNumbers); // [2, 4, 6]
The Collectors.toList() returns a Collector implementation that accumulates the input elements into a new List.
We can use Collectors.toSet() to collect the stream elements into a new Set.
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);
Set<Integer> oddNumbers = numbers.parallelStream().filter(x -> x % 2 != 0).collect(Collectors.toSet());
System.out.println(oddNumbers); // [1, 3, 5]
We can use Collectors.toMap() function to collect the stream elements to a Map. This method accepts two arguments for mapping key and the corresponding value in the Map.
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);
Map<Integer, String> mapOddNumbers = numbers.parallelStream().filter(x -> x % 2 != 0)
.collect(Collectors.toMap(Function.identity(), x -> String.valueOf(x)));
System.out.println(mapOddNumbers); // {1=1, 3=3, 5=5}
We can use Collectors joining() methods to get a Collector that concatenates the input stream CharSequence elements in the encounter order. We can use this to concatenate a stream of strings, StringBuffer, or StringBuilder.
jshell> String value = Stream.of("a", "b", "c").collect(Collectors.joining());
value ==> "abc"
jshell> String valueCSV = Stream.of("a", "b", "c").collect(Collectors.joining(","));
valueCSV ==> "a,b,c"
jshell> String valueCSVLikeArray = Stream.of("a", "b", "c").collect(Collectors.joining(",", "{", "}"));
valueCSVLikeArray ==> "{a,b,c}"
jshell> String valueObject = Stream.of("1", new StringBuffer("2"), new StringBuilder("3")).collect(Collectors.joining());
valueObject ==> "123"
Output:
Java Stream collect() is mostly used to collect the stream elements to a collection. It’s a terminal operation. It takes care of synchronization when used with a parallel stream. The Collectors class provides a lot of Collector implementation to help us out.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
3. Stream collect() to Map List numbers = List.of(1, 2, 3, 4, 5, 6); Map mapOddNumbers = numbers.stream() … why parallel stream? a normal would do it aswell?
- Rudi