Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Stream - .max() with duplicates

Tags:

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.

like image 450
Andrew Mairose Avatar asked Aug 03 '15 14:08

Andrew Mairose


People also ask

How do I find duplicates in a string in Java 8?

In Java 8 Stream, filter with Set. Add() is the fastest algorithm to find duplicate elements, because it loops only one time. Set<T> items = new HashSet<>(); return list. stream() .

How do I filter duplicates in Java 8?

You can use the Stream. distinct() method to remove duplicates from a Stream in Java 8 and beyond. The distinct() method behaves like a distinct clause of SQL, which eliminates duplicate rows from the result set.

Can we use same stream twice?

From the documentation: A stream should be operated on (invoking an intermediate or terminal stream operation) only once. A stream implementation may throw IllegalStateException if it detects that the stream is being reused. So the answer is no, streams are not meant to be reused.


1 Answers

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.

like image 134
ka4eli Avatar answered Oct 26 '22 11:10

ka4eli