Java 8 How to use collectors averagingInt, averagingLong, averagingDouble with examples
This tutorial explains how to use the predefined averaging collectors returned by
Where,
- input for all 3 collectors is a FunctionClick to Read Tutorial on Function functional interfaces which extracts an
- output is a Collector with finisherClick to Read tutorial on 4 components of Collectors incl. 'finisher'(return type) of type
The average operation in mathematics can be applied to a numeric value only. So to apply the averaging collectors one may assume that the streams need to carry numeric values. Java designers understand that it is not necessary that the objects in the stream themselves may be numeric; rather these objects may have a numerical attribute which needs to be averaged, or their might be some calculation done first on the objects to derive an equivalent numerical value and then average those values. In keeping with this understanding, the only parameter to the averaging collector creation methods accepts a function instance which converts the stream objects to their equivalent numerical values, or, more simply put, these functions extract the numerical value to be averaged from the stream objects.
Since, there already are predefined functions
OUTPUT of the above code
Explanation of the code
Collectors.averagingInt()
, Collectors.averagingLong()
and Collectors.averagingDouble()
methods with examples. It first explains the method definitions of these 3 methods and then shows averaging collectors’ usage using Java 8 code example, along with detailed explanation of the code.
Definition of averaging collectors
All 3 averaging collectors have very similar signatures which are as follows - public static <T> Collector<T, ?, Double> averagingInt(ToIntFunction<? super T> mapper)
public static <T> Collector<T, ?, Double> averagingLong(ToLongFunction<? super T> mapper)
public static <T> Collector<T, ?, Double> averagingDouble(ToDoubleFunction<? super T> mapper)
- input for all 3 collectors is a FunctionClick to Read Tutorial on Function functional interfaces which extracts an
int
/long
/double
type of value as it works on the objects of the stream.The definitions in fact use the predefined ToIntFunction
/ ToLongFunction
/ ToDoubleFunction
which I will explain in the next section.- output is a Collector with finisherClick to Read tutorial on 4 components of Collectors incl. 'finisher'(return type) of type
Double
.
How the averaging collector works
Given a stream of objects, averaging collectors provided by the methods Collectors.averagingInt()
, Collectors.averagingLong()
and Collectors.averagingDouble()
reduce these objects to an average of their numerical value/numerical value equivalent.Since, there already are predefined functions
ToIntFunction
, ToLongFunction
, and ToDoubleFunctions
existing in java.util.functionClick to Read Tutorial on Overview of Java 8’s new java.util.function package package for exactly such conversions of objects to their primitive equivalent value in int
, long
and double
respectively, the same have been used for defining the conversion functions used by averaging collector definitions we saw above.
Example showing usage of collectors - averagingInt, averagingLong, averagingDouble
Problem Description: Given a stream of Employee
objects, we want to -
- Find the average age of employees. Attribute
age
is of typeint
. - Find the average leaves(taken) of employees. Attribute
leaves
is of typelong
. - Find the average salary of employees. Attribute
salary
is of typeDouble
.
Java 8 Code Example for averagingInt, averagingLong, averagingDouble
package com.javabrahman.java8.collector;
import com.javabrahman.java8.Employee;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class AveragingWithCollectors {
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.averagingInt()
Double avgAge = employeeList
.stream()
.collect(Collectors.averagingInt(Employee::getAge));
System.out.println("Average age using Collectors.averagingInt: " + avgAge);
//Using Collectors.averagingLong()
Double avgLeaves = employeeList
.stream()
.collect(Collectors.averagingLong(Employee::getLeaves));
System.out.println("Average leaves using Collectors.averagingLong: " + avgLeaves);
//Using Collectors.averagingDouble()
Double avgSalary = employeeList
.stream()
.collect(Collectors.averagingDouble(Employee::getSalary));
System.out.println("Average salary using Collectors.averagingDouble: " + avgSalary);
}
}
//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
}
Average age using Collectors.averagingInt: 41.2 Average leaves using Collectors.averagingLong: 293.6 Average salary using Collectors.averagingDouble: 9800.0
AveragingWithCollectors
class contains a static list ofEmployee
objects -employeeList
.- a stream of
Employee
objects 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 averaging collectors is same until this point. From here it proceeds slightly different for the three -
Collectors.averagingInt Collector
Collector
returned byCollectors.averagingInt()
method is passed as a parameter to theStream.collect()
method.- averagingInt collector takes
ToIntFunction
instance as an input which in this case is specified using the method reference Click to Read Tutorial on Java 8's Method References to theEmployee
’s age passed as the sort key using - “Employee::getAge
”. - The average age of all employees is then correctly printed as
41.2
.
Collectors.averagingLong collector
Collector
returned byCollectors.averagingLong()
method is passed as a parameter to theStream.collect()
method.- averagingLong collector takes
ToLongFunction
instance as an input which in this case is specified using the method reference to theEmployee
’s leaves passed as the sort key using - “Employee::getLeaves
”. - The average leaves of all employees is then correctly printed as
293.6
.
Collectors.averagingDouble collector
Collector
returned byCollectors.averagingDouble()
method is passed as a parameter to theStream.collect()
method.- averagingDouble collector takes
ToDoubleFunction
instance as an input which in this case is specified using the method reference to theEmployee
’s leaves passed as the sort key using - “Employee::getSalary
”. - The average salary of all employees is then correctly printed as
9800.0
.
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