Using Java 8 stream methods to get the last max value

  • A+
Category:Languages

Given a list of items with properties, I am trying to get the last item to appear with a maximum value of said property.

For example, for the following list of objects:

t  i A: 3 D: 7 * F: 4 C: 5 X: 7 * M: 6 

I can get one of the Things with the highest i:

Thing t = items.stream()         .max(Comparator.comparingLong(Thing::getI))         .orElse(null); 

However, this will get me Thing t = D. Is there a clean and elegant way of getting the last item, i.e. X in this case?

One possible solution is using the reduce function. However, the property is calculated on the fly and it would look more like:

Thing t = items.stream()         .reduce((left, right) -> {             long leftValue = valueFunction.apply(left);             long rightValue = valueFunction.apply(right);             return leftValue > rightValue ? left : right;         })         .orElse(null); 

The valueFunction now needs to be called nearly twice as often.

Other obvious roundabout solutions are:

  1. Store the object in a Tuple with its index
  2. Store the object in a Tuple with its computed value
  3. Reverse the list beforehand
  4. Don't use Streams

 


Conceptually, you seem to be possibly looking for something like thenComparing using the index of the elements in the list:

Thing t = items.stream()         .max(Comparator.comparingLong(Thing::getI).thenComparing(items::indexOf))         .orElse(null); 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: