
Stream Collectors Example in Java 8 : toList, toCollection, summingInt, groupingBy
The collect operation in stream is a handy terminal operation which is used to accumulate or convert a stream in to collections like List, Set Or Map.It can be used to accumulate data present in a stream and convert into a list or a similar collection.
Similarly we can summarize data according to various criteria.
A collect operation is a combination of 4 elements namely supplier, an accumulator, a combiner and a finisher.
But since Java 8 uses inbuilt collectors, we do not need to implement one for most of our daily operations.
Here are a list of Methods explained below:
1. Collectors.toList()
2. Collectors.toCollection()
3. Collectors.summingInt()
4. Collectors.averagingDouble() and Collectors.averagingInt()
5. Collectors.groupingBy()
Lets the fun begin!!
We will create a List of Employee Objects to explain this tutorial.
The Employee class looks like this. It has a constructor and some getters and setters. Simple right?!!
package codermag.net.java8;
public class Employee {
public String name;
public int age;
Employee(String name, int age) {
this.setName(name);
this.setAge(age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return getName();
}
}
Now lets us look at the program below:
List<Employee> employees = new ArrayList<Employee>();
employees.add(new Employee("John", 35));
employees.add(new Employee("Wendy", 43));
employees.add(new Employee("Scott", 22));
employees.add(new Employee("Joe", 17));
employees.add(new Employee("Brad", 43));
Stream<Employee> employeeStream = employees.stream();
1. Lets collect all the Employee Names and collect them in a List
The toList() operation in one of the basic operations of the Collectors class.The toList() function in Collectors helps to convert a Stream to a List as shown below.
// Accumulate names into a List
List<String> listOfNames = employeeStream
.map(Employee::getName)
.collect(Collectors.toList());
System.out.println(listOfNames ); //[John, Wendy, Scott, Joe, Brad]
2. Lets filter names starting with the letter 'J'.
// Filter names starting with 'J'
List<String> listOfNamesStartingWithJ = employeeStream
.filter(x -> x.getName().startsWith("J"))
.map(Employee::getName)
.collect(Collectors.toList());
System.out.println(listOfNamesStartingWithJ); //[John, Joe]
3. Get the List of person objects whose name starts with 'J'.
For this case we are introducing an intermediate filter() method to filter data based on criteria.
List<Employee> listOfPersons = employeeStream
.filter(x -> x.name.startsWith("J"))
.collect(Collectors.toList());
System.out.println(listOfPersons); //[John, Joe]
4. Lets sort the names using TreeSet.
A similar operation is toCollection() operation of Collectors class in Java 8.Unlike the toList() Collector class, this is more generalized method for converting to collections.
// Accumulate names into a TreeSet
Set<String> setOfName = employeeStream
.map(Employee::getName)
.collect(Collectors.toCollection(TreeSet::new));
System.out.println(setOfName); //[Brad, Joe, John, Scott, Wendy]
5. Get the sum of ages of all Employees.
Collectors in Java 8 are versatile and there are various utility methods which makes ourlife much more simplier. For example the summingInt() of Collectors class in Java 8 lets you
calculate the sum of attributes of Stream data.
int totalAge = employeeStream
.collect(Collectors.summingInt(Employee::getAge));
System.out.println(totalAge); //10
6. Get the average of the ages of all employees.
Collectors class in Java 8 has functions like averagingDouble() and averagingInt()to directly calculate the average of nummeric values.
Double averageAge=employeeStream
.collect(Collectors.averagingDouble(emp -> emp.age));
System.out.println(averageAge); // 32.0
7. Group by a particular attribute.
In java 8 Collectors, probably one of the most talked about method is the groupingBy() method.The groupingBy() method in Collectors class in Java 8 lets you group data based on criterias set by you.
For example the following method uses the groupingBy() Collectors class method to group employees based
on their ages.
Map<Integer, List<Employee>> empMap = employeeStream
.collect(Collectors.groupingBy(x -> x.age));
empMap.forEach((age, empList) -> System.out.format(
"Employees of age %s are : %s\n", age, empList));
/*
Employees of age 17 are : [Joe]
Employees of age 35 are : [John]
Employees of age 22 are : [Scott]
Employees of age 43 are : [Wendy, Brad]
*/