Using Java 8 stream methods to get the last max value

Druckles :

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
jvdmr :

Remove the equals option (don't return 0 if the compared numbers are equal, return -1 instead) from the comparator (ie. write your own comparator that doesn't include an equals option):

Thing t = items.stream()
        .max((a, b) -> a.getI() > b.getI() ? 1 : -1)
        .orElse(null);

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=35786&siteId=1