'Java 8 Stream - .max() with duplicates
So I have a collection of objects that have a step variable that can be 1 - 4.
public class MyClass {
private Long step;
//other variables, getters, setters, etc.
}
Collection<MyClass> myOjbects = /*get collection*/;
Then I would like to get one instance of MyClass
from the collection that has the maximum step value, so I do:
final Optional<MyClass> objectWithMaxStep =
myObjects.stream().max(Comparator.comparing(MyClass::getStep));
However, there are situations where there will be multiple MyClass
instances in the collection that have a step equal to 4.
So, my question is, how is it determined which instance is returned in the Optional
, or does it throw an exception when multiple objects in the stream have the max value that is being compared?
The Java 8 documentation for the max()
function does not specify what will occur in this situation.
Solution 1:[1]
max
is implemented reducing the collection with maxBy
:
public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
}
Here comparator.compare(a, b) >= 0 ? a : b
you can see that when 2 elements are equal, i.e. compare
returns 0, then the first element is returned. Therefore in your case will be returned first in a collection MyClass
object with highest step
.
UPDATE: As user the8472 correctly mentioned in comments, you shouldn't rely on implementation which isn't explicitly specified by javadocs. But you can write unit test on max
method to know if it's logic has changed in standard java library.
Solution 2:[2]
Since the ordering isn't specified by the documentation, then the order can be different in future versions of the JVM or in different implementations of the JVM.
If you care which one is returned then my advice is to write your own reduction operation or Collector to behave however you desire. That way future implementations can't change it and you can explicitly say what will happen.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Community |
Solution 2 | dkatzel |