What is the best way to get List<MyCustomObject>
from List<MyCustomObject>
that have maximum value of some property?
I can write my own Comparator
:
Comparator<MyCustomObject> cmp = Comparator.comparing(MyCustomObject::getIntField);
Then use it in a stream
:
Optional<MyCustomObject> max = list.stream().max(cmp);
But I'm getting only one element. Is there a simple way to return all MyCustomObject
that have maximum IntField
and not just the first one?
You only know the maximum value of the relevant property after you iterate over all the elements of the List
, so one way of find the elements having the max value is to group the elements by that property into a sorted Map and get the last value:
List<MyCustomObject> max = list.stream()
.collect(Collectors.groupingBy (MyCustomObject::getIntField,
TreeMap::new,
Collectors.toList ()))
.lastEntry ()
.getValue ();
However, this performs more work then you actually need, and costs O(NlogN)
due to the sorting. If you don't mind splitting the problem into two steps (first finding the maximum value and then collecting the elements having a property with that value), you'll have better running time (O(N)
).
Since I don't have your custom object, I couldn't test the above code, but I tested similar code that takes a Stream
of String
s and returns all the String
s having the max length:
List<String> max = Stream.of ("ddd","aa","EEEE","a","BB","CCC1")
.collect(Collectors.groupingBy (String::length,
TreeMap::new,
Collectors.toList ()))
.lastEntry ()
.getValue ();
System.out.println (max);
This returns:
[EEEE, CCC1]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With