[toList()](<https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toList-->)
and [toSet()](<https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toSet-->)
Elements from a [Stream](<https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html>)
can be easily collected into a container by using the [Stream.collect](<https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#collect-java.util.stream.Collector->)
operation:
System.out.println(Arrays
.asList("apple", "banana", "pear", "kiwi", "orange")
.stream()
.filter(s -> s.contains("a"))
.collect(Collectors.toList())
);
// prints: [apple, banana, pear, orange]
Other collection instances, such as a [Set](<https://docs.oracle.com/javase/8/docs/api/java/util/Set.html>)
, can be made by using other [Collectors](<https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html>)
built-in methods. For example, [Collectors.toSet()](<https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toSet-->)
collects the elements of a Stream
into a [Set](<https://docs.oracle.com/javase/8/docs/api/java/util/Set.html>)
.
[List](<https://docs.oracle.com/javase/8/docs/api/java/util/List.html>)
or [Set](<https://docs.oracle.com/javase/8/docs/api/java/util/Set.html>)
According to documentation of [Collectors#toList()](<https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toList-->)
and [Collectors#toSet()](<https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toSet-->)
, there are no guarantees on the type, mutability, serializability, or thread-safety of the [List](<https://docs.oracle.com/javase/8/docs/api/java/util/List.html>)
or [Set](<https://docs.oracle.com/javase/8/docs/api/java/util/Set.html>)
returned.
For explicit control over the implementation to be returned, [Collectors#toCollection(Supplier)](<https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toCollection-java.util.function.Supplier->)
can be used instead, where the given supplier returns a new and empty collection.
// syntax with method reference
System.out.println(strings
.stream()
.filter(s -> s != null && s.length() <= 3)
.collect(Collectors.toCollection(ArrayList::new))
);
// syntax with lambda
System.out.println(strings
.stream()
.filter(s -> s != null && s.length() <= 3)
.collect(Collectors.toCollection(() -> new LinkedHashSet<>()))
);
Collecting Elements using toMap
Collector accumulates elements into a Map, Where key is the Student Id and Value is Student Value.
List<Student> students = new ArrayList<Student>();
students.add(new Student(1,"test1"));
students.add(new Student(2,"test2"));
students.add(new Student(3,"test3"));
Map<Integer, String> IdToName = students.stream()
.collect(Collectors.toMap(Student::getId, Student::getName));
System.out.println(IdToName);
Output :
{1=test1, 2=test2, 3=test3}
The Collectors.toMap has another implementation `Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction)`.The mergeFunction is mostly used to select either new value or retain old value if the key is repeated when adding a new member in the Map from a list.
The mergeFunction often looks like: (s1, s2) -> s1
to retain value corresponding to the repeated key, or (s1, s2) -> s2
to put new value for the repeated key.
Collecting Elements to Map of Collections
Example: from ArrayList to Map<String, List<>>
Often it requires to make a map of list out of a primary list. Example: From a student of list, we need to make a map of list of subjects for each student.