Java 8 – Collectors
This section describes the Collectors class which provides operations that can be performed at the final step of processing a Stream of objects.
Examples
The examples illustrated below use the following Employee POJO class:
package org.examples;
public class Employee { private String name; private Integer hourRate; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getHourRate() { return hourRate; } public void setHourRate(Integer hourRate) { this.hourRate = hourRate; } public Employee(String name, Integer hourRate) { super(); this.name = name; this.hourRate = hourRate; } @Override public String toString() { return “Employee [name=” + name + “, hourRate=” + hourRate + “]”; } } |
We create a list of Employees to perform operations in the examples:
List<Employee> employees = Arrays.asList(new Employee(“Jack”, 10), new Employee(“Robert”, 50), new Employee(“David”, 30), new Employee(“Abhi”, 20), new Employee(“Daniel”,20), new Employee(“Ankit”,30), new Employee(“Nilton”,40), new Employee(“Joseph”,50)); |
Following are the various methods to perform operations on the above Employees list:
This method returns a Collector which collects all input elements into a new List.
This example shows collects names of employees into a list.
This method returns a Collector which collects all input elements into a new Set.
This examples collects hour rates of employees into a set (unique rates).
This method returns a Collector which collects input elements into a new Map.
This examples collects employees into a Map with name as key and hourRate as value.
List<String> names = employees.stream().map(emp->emp.getName()).collect(Collectors.toList()); System.out.println(names); |
Output: [Jack, Robert, David, Abhi, Daniel, Ankit, Nilton, Joseph] |
Set<Integer> rates = employees.stream().map(emp->emp.getHourRate()).collect(Collectors.toSet()); System.out.println(rates);
|
Output: [50, 20, 40, 10, 30] |
Map<String,Integer> map = employees.stream().collect(Collectors.toMap(Employee::getName, Employee::getHourRate)); System.out.println(map); |
Output: {Robert=50, Nilton=40, Joseph=50, David=30, Daniel=20, Jack=10, Abhi=20, Ankit=30} |
This method returns a Collector which collects the elements into the specified (custom) Collection.
This example collects list of employees into a LinkedList.
LinkedList<Employee> linkList = employees.stream().collect(Collectors.toCollection(LinkedList::new)); System.out.println(linkList);
|
Output: [Employee [name=Jack, hourRate=10], Employee [name=Robert, hourRate=50], Employee [name=David, hourRate=30], Employee [name=Abhi, hourRate=20], Employee [name=Daniel, hourRate=20], Employee [name=Ankit, hourRate=30], Employee [name=Nilton, hourRate=40], Employee [name=Joseph, hourRate=50]] |
This method returns a collector that collects the elements into the given collector and then performs an action on it.
This example collects first 3 employees into a list and then makes it unmodifiable.
List<Employee> empList = employees.stream().limit(3).collect( Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)); System.out.println(empList); |
Output: [Employee [name=Jack, hourRate=10], Employee [name=Robert, hourRate=50], Employee [name=David, hourRate=30]] |
It is a collector that returns sum of the elements.
This example returns the total hour rate of all employees.
It is a collector that returns average of the elements.
This example returns the average hour rate of all employees.
This method returns a Collector which concatenates the elements separated by specified delimiter.
This example prints a comma-separated list of names of employees.
Integer totalRate = employees.stream().collect(Collectors.summingInt(emp->emp.getHourRate())); System.out.println(totalRate); |
Output: 250 |
Double avgRate = employees.stream() .collect(Collectors.averagingInt(emp->emp.getHourRate())); System.out.println(avgRate);} |
Output: 31.25 |
String names = employees.stream().map(emp–>emp.getName()) .collect(Collectors.joining(“,”)); System.out.println(names); |
Output: Jack,Robert,David,Abhi,Daniel,Ankit,Nilton,Joseph |
This method returns a Collector that returns maximum/minimum element in a stream according to specified comparator.
This example prints the maximum and minimum hour rate of employees.
Optional<Integer> maxRate = employees.stream() .map(emp–>emp.getHourRate()) .collect(Collectors.maxBy(Comparator.naturalOrder())); System.out.println(“Max rate = “+maxRate);
Optional<Integer> minRate = employees.stream() .map(emp->emp.getHourRate()) .collect(Collectors.minBy(Comparator.naturalOrder())); System.out.println(“Min rate = “+minRate);
|
Output: Max rate = Optional[50] Min rate = Optional[10] |
This method returns a Collector that counts the number of elements.
This example counts the number of employees with hour rate greater than 20.
Long empCount = employees.stream() .filter(emp->emp.getHourRate()>20) .collect(Collectors.counting()); System.out.println(empCount);}
|
Output: 5 |
These collectors return a special class Int/Long/DoubleSummaryStatistics which contains statistical information like sum, min, max, average etc of input elements.
This example returns statistical information of hour rates of employees.
IntSummaryStatistics rateStats = employees.stream() .collect(Collectors.summarizingInt(emp->emp.getHourRate())); System.out.println(rateStats); |
Output: IntSummaryStatistics{count=8, sum=250, min=10, average=31.250000, max=50} |
This collector groups the input elements according to specified property and collects the result in a Map.
This example groups the employees according to hourRate and returns list of employees in each group.
Map<Integer,List<Employee>> rateGroup = employees.stream() .collect(Collectors.groupingBy(Employee::getHourRate)); System.out.println(rateGroup);
|
Output: {50=[Employee [name=Robert, hourRate=50], Employee [name=Joseph, hourRate=50]], 20=[Employee [name=Abhi, hourRate=20], Employee [name=Daniel, hourRate=20]], 40=[Employee [name=Nilton, hourRate=40]], 10=[Employee [name=Jack, hourRate=10]], 30=[Employee [name=David, hourRate=30], Employee [name=Ankit, hourRate=30]]} |
This example groups the employees according to hourRate and counts the number of employees in each group, using counting() method.
Map<Integer,Long> rateGroup = employees.stream() .collect(Collectors.groupingBy(Employee::getHourRate,Collectors.counting())); System.out.println(rateGroup); |
Output: {50=2, 20=2, 40=1, 10=1, 30=2} |
This example groups the employees according to hourRate and returns the names of employees in each group, using mapping() method.
Map<Integer,List<String>> rateGroup = employees.stream() .collect(Collectors.groupingBy(Employee::getHourRate, Collectors.mapping(Employee::getName,Collectors.toList()))); System.out.println(rateGroup); |
Output: {50=[Robert, Joseph], 20=[Abhi, Daniel], 40=[Nilton], 10=[Jack], 30=[David, Ankit]} |
This method partitions the input elements according to specified Predicate and returns a Map with Boolean values as keys and collections as values.
This example partitions the employees on basis of employees who have hourRate greater than 30.
Map<Boolean,List<Employee>> rateGreaterThan30 = employees.stream().collect( Collectors.partitioningBy(emp -> emp.getHourRate() > 30, Collectors.toList())); System.out.println(rateGreaterThan30); |
Output: {false=[Employee [name=Jack, hourRate=10], Employee [name=David, hourRate=30], Employee [name=Abhi, hourRate=20], Employee [name=Daniel, hourRate=20], Employee [name=Ankit, hourRate=30]], true=[Employee [name=Robert, hourRate=50], Employee [name=Nilton, hourRate=40], Employee [name=Joseph, hourRate=50]]} |
Leave a Reply