Java 8 How to use Collectors summarizingInt, summarizingLong, summarizingDouble with examples
This tutorial explains how to use the predefined summarizing collectors returned by
Where,
- input for all 3 collectors is a FunctionClick to Read Tutorial on Function interface which extracts an
- output is a Collector with finisherClick to Read tutorial on 4 components of Collectors incl. 'finisher'(return type) of type
How the summarizing collector works
Given a stream of objects, summarizing collectors provided by the methods
The statistical attributes encapsulated by the summary statistics classes are -
OUTPUT of the above code
Explanation of the code
Collectors.summarizingInt(), Collectors.summarizingLong() and Collectors.summarizingDouble() methods with examples. It first explains the method definitions of these 3 methods, with insights into the structure of the Summary Statistics classes which encapsulate the calculated statistics returned by the collectors. It then shows how to use the summarizing collectors with a Java 8 code example, along with detailed explanation of the code.
Definition of summarizing collectors
The 3 summarizing collectors have almost identical signatures except for the type of data(int/ long/ double) they handle -
public static <T> Collector<T, ?, IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper) public static <T> Collector<T, ?, LongSummaryStatistics> summarizingLong(ToLongFunction<? super T> mapper) public static <T> Collector<T, ?, DoubleSummaryStatistics> summarizingDouble(ToDoubleFunction<? super T> mapper)Where,
- input for all 3 collectors is a FunctionClick to Read Tutorial on Function interface which extracts an
int/long/double type of value as it works on the objects of the stream.(Note - The definitions use the predefined ToIntFunction/ ToLongFunction/ ToDoubleFunction interfaces as the input parameter types, instead of generic Function, as the function descriptorsClick to Read tutorial on Java 8 Function Descriptors of these interfaces match the requirements of summarizing collectors)- output is a Collector with finisherClick to Read tutorial on 4 components of Collectors incl. 'finisher'(return type) of type
IntSummaryStatistics/ LongSummaryStatistics/ DoubleSummaryStatistics.
Collectors.summarizingInt(), Collectors.summarizingLong() and Collectors.summarizingDouble() calculate a bunch of statistical calculations for a given numerical value derived from the stream's objects, and return these statistics encapsulated inside objects of specially defined statistical classes for this purpose viz. IntSummaryStatistics, LongSummaryStatistics & DoubleSummaryStatistics.The statistical attributes encapsulated by the summary statistics classes are -
- count of numeric value derived
- sum of values
- minimum value
- maximum value
- average of all values
(getCount(), getSum()...) to retrieve the computed statistical values individually as per your requirement.ToIntFunction, ToLongFunction, and ToDoubleFunctions, defined as the input parameter for summarizing methods, are predefined functional interfaces in java.util.functionClick to Read Tutorial on Overview of Java 8’s new java.util.function package package. These interfaces convert objects to their primitive equivalent value in int, long and double types, and their use in the definition allows for precisely specifying the 'type' of Function expected for the summarizing methods instead of the more general Function<T,R> definition.
Example showing usage of collectors - summarizingInt, summarizingLong, summarizingDouble
Problem Description: Given a stream of Employee objects, we want to -
- Find the summary of statistics of employee
agewhich is of typeint. - Find the summary of statistics of employee
leaveswhich is of typelong. - Find the summary of statistics of employee
salarywhich is of typedouble.
Java 8 Code Example for summarizingInt, summarizingLong, summarizingDouble
package com.javabrahman.java8.collector;
import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.LongSummaryStatistics;
import java.util.DoubleSummaryStatistics;
import java.util.stream.Collectors;
import com.javabrahman.java8.Employee;
public class SummarizingCollectors {
static List<Employee> employeeList
= Arrays.asList(new Employee("Tom Jones", 45, 15000.00,190),
new Employee("Tom Jones", 45, 7000.00,220),
new Employee("Ethan Hardy", 65, 8000.00,1008),
new Employee("Nancy Smith", 22, 10000.00,5),
new Employee("Deborah Sprightly", 29, 9000.00,45));
public static void main(String[] args) {
//Using Collectors.summarizingInt()
IntSummaryStatistics intSummaryStatistics = employeeList
.stream()
.collect(Collectors.summarizingInt(Employee::getAge));
System.out.println("IntSummaryStatistics for age: " + intSummaryStatistics);
//Using Collectors.summarizingLong()
LongSummaryStatistics longSummaryStatistics = employeeList
.stream()
.collect(Collectors.summarizingLong(Employee::getLeaves));
System.out.println("LongSummaryStatistics for leaves: " + longSummaryStatistics);
//Using Collectors.summarizingDouble()
DoubleSummaryStatistics doubleSummaryStatistics = employeeList
.stream()
.collect(Collectors.summarizingDouble(Employee::getSalary));
System.out.println("DoubleSummaryStatistics for salary: " + doubleSummaryStatistics);
}
}
//Employee.java POJO class
package com.javabrahman.java8;
import java.text.DecimalFormat;
public class Employee {
private String name;
private Integer age;
private Double salary;
private long leaves;
public Employee(String name, Integer age, Double salary, long leaves) {
this.name = name;
this.age = age;
this.salary = salary;
this.leaves = leaves;
}
//Standard getters & setters for name, age, salary and leaves go here
//Standard equals() & hashcode() methods go here
}
IntSummaryStatistics for age: IntSummaryStatistics{count=5, sum=206, min=22, average=41.200000, max=65}
LongSummaryStatistics for leaves: LongSummaryStatistics{count=5, sum=1468, min=5, average=293.600000, max=1008}
DoubleSummaryStatistics for salary: DoubleSummaryStatistics{count=5, sum=49000.000000, min=7000.000000, average=9800.000000, max=15000.000000}
SummarizingCollectorsclass contains a static list ofEmployeeobjects -employeeList.- A stream of
Employeeobjects is created usingList.stream()method. - Stream of employees is pipelinedClick to Read Tutorial explaining Concept of Pipelines in Computing to the
collect()terminal operationClick to Read Tutorial explaining intermediate & terminal Stream operations. - The code for 3 summarizing collectors is same until this point. From here it proceeds slightly different for the three -
Collectors.summarizingInt CollectorCollectorreturned byCollectors.summarizingInt()method is passed as a parameter to theStream.collect()method.- summarizingInt collector takes
ToIntFunctioninstance as an input which in this case is specified using the method reference Click to Read Tutorial on Java 8's Method References toEmployee’s age, i.e. “Employee::getAge”. This method reference acts as theToIntFunctioninstance which extracts theage(of typeint) from allEmployeeobjects in the stream. AnIntSummaryStatisticsinstance is then returned as output by the summarizing collector. - The output variable
intSummaryStatisticsis then printed and the age related statistics of all employees are correctly printed as shown in the output above.
Collectors.summarizingLong CollectorCollectorreturned byCollectors.summarizingLong()method is passed as a parameter to theStream.collect()method.- summarizingLong collector takes
ToLongFunctioninstance as an input which in this case is specified using the method reference toEmployee’s leave, i.e. “Employee::getLeaves”. This method reference acts as theToLongFunctioninstance which extracts theleaves(of typelong) from allEmployeeobjects in the stream. ALongSummaryStatisticsinstance is then returned as output by the summarizing collector. - The output variable
longSummaryStatisticsis then printed and the leaves related statistics of all employees are correctly printed as shown in the output above.
Collectors.summarizingDouble CollectorCollectorreturned byCollectors.summarizingDouble()method is passed as a parameter to theStream.collect()method.- summarizingDouble collector takes
ToDoubleFunctioninstance as an input which in this case is specified using the method reference toEmployee’s salary, i.e. “Employee::getSalary”. This method reference acts as theToDoubleFunctioninstance which extracts thesalary(of typedouble) from allEmployeeobjects in the stream. AnDoubleSummaryStatisticsinstance is then returned as output by the summarizing collector. - The output variable
doubleSummaryStatisticsis then printed and the leaves related statistics of all employees are correctly printed as shown in the output above.
Java 8 Collectors' Tutorials on JavaBrahman
Understanding Basics of Java 8 CollectorsClick to Read Tutorial explaining basics of Java 8 CollectorsCollectors.groupingBy()Click to Read Tutorial on Grouping with CollectorsCollectors.partitioningBy()Click to Read Partitioning using Collectors TutorialCollectors.counting()Click to Read Counting with Collectors Tutorial Collectors.maxBy()/minBy()Click to Read Tutorial on finding max/min with CollectorsCollectors.joining()Click to Read Tutorial on joining as a String using CollectorsCollectors.collectingAndThen()Click to Read Tutorial on collectingAndThen CollectorCollectors.averagingInt() /averagingLong() /averagingDouble()Click to Read Tutorial on Averaging CollectorCollectors.toCollection()Click to Read Tutorial on Collectors.toCollection CollectorCollectors.mapping()Click to Read Tutorial on Mapping Collector
Understanding Basics of Java 8 CollectorsClick to Read Tutorial explaining basics of Java 8 CollectorsCollectors.groupingBy()Click to Read Tutorial on Grouping with CollectorsCollectors.partitioningBy()Click to Read Partitioning using Collectors TutorialCollectors.counting()Click to Read Counting with Collectors Tutorial Collectors.maxBy()/minBy()Click to Read Tutorial on finding max/min with CollectorsCollectors.joining()Click to Read Tutorial on joining as a String using CollectorsCollectors.collectingAndThen()Click to Read Tutorial on collectingAndThen CollectorCollectors.averagingInt() /averagingLong() /averagingDouble()Click to Read Tutorial on Averaging CollectorCollectors.toCollection()Click to Read Tutorial on Collectors.toCollection CollectorCollectors.mapping()Click to Read Tutorial on Mapping Collector