Java 8 How to use collectors averagingInt, averagingLong, averagingDouble with examples
This tutorial explains how to use the predefined averaging collectors returned by
[su_spacer size="15"]
[su_spacer size="15"]
Where,
- input for all 3 collectors is a FunctionClick to Read Tutorial on Function functional interfaces which extracts an
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)
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.
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 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
.
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
[/su_note]