Collectors Flashcards
Static Imports
Typically, we can find all the predefined implementations in the Collectors class.
import static java.util.stream.Collectors.*;
Collectors.toCollection()
When using the toSet() and toList() collectors, we can’t make any assumptions about their implementations, ie with toList() we cannot assume that we will get a LinkedList implementation
List<String> result = givenList.stream()
.collect(toCollection(LinkedList::new))
In above, result is collected to a LinkedList implementation</String>
Collectors.toList()
Collect all Stream elements into a List instance. The important thing to remember is that we can’t assume any particular List implementation with this method. If we want to have more control over this, we can use toCollection() instead.
List<String> result = givenList.stream()
.collect(toList());</String>
Collectors.toUnmodifiableList()
List<String> result = givenList.stream()
.collect(toUnmodifiableList());
if we try to modify result we will get an exception
assertThatThrownBy(() -> result.add("foo")) .isInstanceOf(UnsupportedOperationException.class);</String>
Collectors.toSet()
Set<String> result = givenList.stream()
.collect(toSet());</String>
Collectors.toUnmodifiableSet()
Set<String> result = givenList.stream()
.collect(toUnmodifiableSet());</String>
Collectors.toMap()
The toMap() collector can be used to collect Stream elements into a Map instance. To do so, we need to provide two functions: keyMapper() and valueMapper().
keyMapper() to extract a Map key from a Stream element. we can use valueMapper() to extract a value associated with a given key
Map<String, Integer> result = givenList.stream()
.collect(toMap(Function.identity(), String::length))
Function.identity() is just a shortcut for defining a function that accepts and returns the same value
If it sees duplicate keys, it immediately throws an IllegalStateException.
In such cases with key collision, we should use toMap() with another signature
Map<String, Integer> result = givenList.stream()
.collect(toMap(Function.identity(), String::length, (item, identicalItem) -> item));
The third argument here is a BinaryOperator(), where we can specify how we want to handle collisions. In this case, we’ll just pick any of these two colliding values because we know that the same strings will always have the same lengths too.
Collectors.toUnmodifiableMap()
Map<String, Integer> result = givenList.stream() .collect(toUnmodifiableMap(Function.identity(), String::length))
assertThatThrownBy(() -> result.put(“foo”, 3)) .isInstanceOf(UnsupportedOperationException.class);
Collectors.collectingAndThen()
CollectingAndThen() is a special collector that allows us to perform another action on a result straight after collecting ends.
Let’s collect Stream elements to a List instance, and then convert the result into an ImmutableList instance:
List<String> result = givenList.stream()
.collect(collectingAndThen(toList(), ImmutableList::copyOf))</String>
Collectors.joining()
The Joining() collector can be used for joining Stream<String> elements.
String result = givenList.stream() .collect(joining());
or
String result = givenList.stream()
.collect(joining(" "));</String>
Collectors.counting()
Counting() is a simple collector that allows for the counting of all Stream elements.
Collectors.summarizingDouble/Long/Int()
SummarizingDouble/Long/Int is a collector that returns a special class containing statistical information about numerical data in a Stream of extracted elements.
DoubleSummaryStatistics result = givenList.stream()
.collect(summarizingDouble(String::length));
assertThat(result.getAverage()).isEqualTo(2);
assertThat(result.getCount()).isEqualTo(4);
assertThat(result.getMax()).isEqualTo(3);
assertThat(result.getMin()).isEqualTo(1);
assertThat(result.getSum()).isEqualTo(8);
Collectors.averagingDouble/Long/Int()
Double result = givenList.stream()
.collect(averagingDouble(String::length));
Collectors.summingDouble/Long/Int()
SummingDouble/Long/Int is a collector that simply returns a sum of extracted elements
Double result = givenList.stream()
.collect(summingDouble(String::length));
Collectors.maxBy/minBy
MaxBy() and MinBy() collectors return the biggest/smallest element of a Stream according to a provided Comparator instance.
Optional<String> result = givenList.stream()
.collect(maxBy(Comparator.naturalOrder()));</String>