Collect with toList() and toSet()

Elements from a Stream can be easily collected into a container by using the Stream.collect 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, can be made by using other Collectors built-in methods. For example, Collectors.toSet() collects the elements of a Stream into a Set.


Explicit control over the implementation of List or Set

According to documentation of Collectors#toList() and Collectors#toSet(), there are no guarantees on the type, mutability, serializability, or thread-safety of the List or Set returned.

For explicit control over the implementation to be returned, Collectors#toCollection(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.