To group data in a Stream we can use collect()
method
of the Stream<T> interface.
The collect() method is overloaded with two versions:
<R> R collect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner) <R,A> R collect(Collector<? super T,A,R> collector)
The first version of the collect() method takes three arguments:
We use the following steps to collect the employee names in an ArrayList<String>.
First, create a supplier which returns an
ArrayList<String>
using either of the following statements to create the supplier:
Supplier<ArrayList<String>> supplier = () -> new ArrayList<>();
or
Supplier<ArrayList<String>> supplier = ArrayList::new;
Second, create an accumulator that receives two arguments which is the container returned from the supplier(ArrayList<String> in this case). and the element of the stream.
The accumulator adds the names to the list.
BiConsumer<ArrayList<String>, String> accumulator = (list, name) -> list.add(name); BiConsumer<ArrayList<String>, String> accumulator = ArrayList::add;
Finally, a combiner combines the results into one ArrayList<String>
.
The combiner is used only in a parallel stream.
The following code shows how to use the collect() method to collect the names of all employee in a list.
import java.time.LocalDate; import java.time.Month; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /*from w w w.ja v a 2 s . co m*/ public class Main { public static void main(String[] args) { List<String> names = Employee.persons() .stream() .map(Employee::getName) .collect(ArrayList::new, ArrayList::add, ArrayList::addAll); System.out.println(names); } } class Employee { public static enum Gender { MALE, FEMALE } private long id; private String name; private Gender gender; private LocalDate dob; private double income; public Employee(long id, String name, Gender gender, LocalDate dob, double income) { this.id = id; this.name = name; this.gender = gender; this.dob = dob; this.income = income; } public String getName() { return name; } public static List<Employee> persons() { Employee p1 = new Employee(1, "Jake", Gender.MALE, LocalDate.of(1971, Month.JANUARY, 1), 2343.0); Employee p2 = new Employee(2, "Jack", Gender.MALE, LocalDate.of(1972, Month.JULY, 21), 7100.0); Employee p3 = new Employee(3, "Jane", Gender.FEMALE, LocalDate.of(1973, Month.MAY, 29), 5455.0); Employee p4 = new Employee(4, "Jode", Gender.MALE, LocalDate.of(1974, Month.OCTOBER, 16), 1800.0); Employee p5 = new Employee(5, "Jeny", Gender.FEMALE, LocalDate.of(1975, Month.DECEMBER, 13), 1234.0); Employee p6 = new Employee(6, "Jason", Gender.MALE, LocalDate.of(1976, Month.JUNE, 9), 3211.0); List<Employee> persons = Arrays.asList(p1, p2, p3, p4, p5, p6); return persons; } }
The code above generates the following result.
The second version of the collect() takes an instance of the Collector interface as an argument.
Streams API provides a utility class called Collectors that provides out-of-box implementations for commonly used collectors.
Three of the most commonly used methods of the Collectors class are toList(), toSet(), and toCollection().
The following code collects all names of employee in a List<String>.
import java.time.LocalDate; import java.time.Month; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; // w ww . jav a2s .com public class Main { public static void main(String[] args) { List<String> names = Employee.persons() .stream() .map(Employee::getName) .collect(Collectors.toList()); System.out.println(names); } } class Employee { public static enum Gender { MALE, FEMALE } private long id; private String name; private Gender gender; private LocalDate dob; private double income; public Employee(long id, String name, Gender gender, LocalDate dob, double income) { this.id = id; this.name = name; this.gender = gender; this.dob = dob; this.income = income; } public String getName() { return name; } public static List<Employee> persons() { Employee p1 = new Employee(1, "Jake", Gender.MALE, LocalDate.of(1971, Month.JANUARY, 1), 2343.0); Employee p2 = new Employee(2, "Jack", Gender.MALE, LocalDate.of(1972, Month.JULY, 21), 7100.0); Employee p3 = new Employee(3, "Jane", Gender.FEMALE, LocalDate.of(1973, Month.MAY, 29), 5455.0); Employee p4 = new Employee(4, "Jode", Gender.MALE, LocalDate.of(1974, Month.OCTOBER, 16), 1800.0); Employee p5 = new Employee(5, "Jeny", Gender.FEMALE, LocalDate.of(1975, Month.DECEMBER, 13), 1234.0); Employee p6 = new Employee(6, "Jason", Gender.MALE, LocalDate.of(1976, Month.JUNE, 9), 3211.0); List<Employee> persons = Arrays.asList(p1, p2, p3, p4, p5, p6); return persons; } }
The code above generates the following result.
The following code collects all names in a Set<String>
which keeps only unique elements.
Set<String> uniqueNames = Person.persons() .stream() .map(Person::getName) .collect(Collectors.toSet()); System.out.println(uniqueNames);
We can collect names in a sorted set using the toCollection() method as follows:
import java.time.LocalDate; import java.time.Month; import java.util.Arrays; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import java.util.stream.Collectors; // ww w . jav a2s . co m public class Main { public static void main(String[] args) { SortedSet<String> uniqueSortedNames= Employee.persons() .stream() .map(Employee::getName) .collect(Collectors.toCollection(TreeSet::new)); System.out.println(uniqueSortedNames); System.out.println(uniqueSortedNames); } } class Employee { public static enum Gender { MALE, FEMALE } private long id; private String name; private Gender gender; private LocalDate dob; private double income; public Employee(long id, String name, Gender gender, LocalDate dob, double income) { this.id = id; this.name = name; this.gender = gender; this.dob = dob; this.income = income; } public String getName() { return name; } public static List<Employee> persons() { Employee p1 = new Employee(1, "Jake", Gender.MALE, LocalDate.of(1971, Month.JANUARY, 1), 2343.0); Employee p2 = new Employee(2, "Jack", Gender.MALE, LocalDate.of(1972, Month.JULY, 21), 7100.0); Employee p3 = new Employee(3, "Jane", Gender.FEMALE, LocalDate.of(1973, Month.MAY, 29), 5455.0); Employee p4 = new Employee(4, "Jode", Gender.MALE, LocalDate.of(1974, Month.OCTOBER, 16), 1800.0); Employee p5 = new Employee(5, "Jeny", Gender.FEMALE, LocalDate.of(1975, Month.DECEMBER, 13), 1234.0); Employee p6 = new Employee(6, "Jason", Gender.MALE, LocalDate.of(1976, Month.JUNE, 9), 3211.0); List<Employee> persons = Arrays.asList(p1, p2, p3, p4, p5, p6); return persons; } }
The code above generates the following result.