Using .max () with .stream () on list <>
I would like to ask for an explanation of some code that I was given as a solution to an exercise I am doing in a Java course. Exercise: I have List<>
Workers with different properties (Salary, First Name, Last Name, Email ...) and I am trying to find the highest paid employee and print my name and salary.
I managed to get the highest salary but not the employee name, for example:
Integer maxSalary; maxSalary = roster .stream() .map(Employee :: getSalary) .collect(Collectors.reducing(Integer :: max) .get();
I was then given this little block of code and it works great, but I'm not really sure why it works:
Integer maxSalary; Employee emp2 = roster .stream() .max((p1, p2) -> Integer.compare(p1.getSalary(), p2.getSalary())) .get(); System.out.println("The employee who earns the most is :" + emp2.getName + " and earns : " + emp2.getSalary + " a month.");
I realize this is a Lambda expression using .max
, I just can't figure out why and how does it work?
source share
Optional<T> max(Comparator<? super T> comparator)
explains it all.
Since the intent of the question was to find the employee with the highest salary, the stream is passed directly to the .max
one that consumes the employee comparator
. Since it comparator
is a functional interface, it can be passed as a lambda.
.max
already implemented version of more general reduce
and collect
operations available with java 8
Integer.compare
compares two ints numerically. Therefore, it .max()
returns the employee with the highest salary.
On the other hand, your attempt is specifically trying to get the highest salary.
Greetings. Happy streams.
source share
Function Stream#max
:
Returns the maximum element of this stream according to the supplied comparator. This is a special case of contraction.
As Comparator
is a functional interface that is only implemented compare(T o1, T o2)
, it can be represented by a lambda. Here, lambda (p1, p2) -> Integer.compare(p1.getSalary(), p2.getSalary())
compares salary p1
to salary p2
using standard integer comparison. Therefore, the result will be Employee
with the highest salary.
source share
Optional<T> max(Comparator<? super T> comparator);
Returns the maximum element of this stream as supplied by the Comparator. This is a special case of contraction.
Comparator
is a functional interface that allows you to specify the order in a collection of objects of a particular type.
Here is the functional interface method:
int compare(T o1, T o2);
So, when called max()
, you can pass it a lambda that takes two as an argument Employee
, since it is a stream type Employee
and provides the implementation of comparing two objects Employee
as int compare(Employee o1, Employee o2)
expected:
.max((p1, p2) -> Integer.compare(p1.getSalary(), p2.getSalary()))
source share
It's pretty simple: in your solution, you convert Employees to your salaries and then find the maximum number among the numbers. In the second (and correct) solution, you are not performing any transformation: you are comparing the employees themselves according to certain criteria . And the criteria in your case is the salary. Therefore, in the end, he max()
receives not the maximum number, but the "maximum employee" (for salary).
source share