2

I have the following pojo:

class MyPojo {
    String name;
    int priority;
}

I have a List<MyPojo>. Now, I want to retrieve all elements which have the highest priority. The order of those elements does not matter.

Is this possible with Java streams? I think I should first group by priority and then get all elements belonging to the highest priority, but I am not sure how to do this in an efficient manner.

  • 2
    You can write a custom collector called `maxList` as @Stuart Marks suggests here: https://stackoverflow.com/questions/29334404/how-to-force-max-to-return-all-maximum-values-in-a-java-stream – Ravindra Ranwala Oct 12 '20 at 07:33
  • 1
    Intestsing stuff, the ad-hoc collector is what I *really* wanted, as this is what I had in mind when thinking procedurally. –  Oct 12 '20 at 07:43
  • It's more elegant solution, and it promotes reuse too. – Ravindra Ranwala Oct 12 '20 at 07:56

2 Answers2

5

You should cast it to IntStream and get the max() out of it. And then get every pojos with this value.

import java.util.List;
import java.util.stream.Collectors;

class MyPojo {
    String name;
    int priority;

    public int getPriority() {
        return priority;
    }
}

public class Main {
    public static void main(String[] args) {
        List<MyPojo> list = null;
        int max = list.stream().mapToInt(MyPojo::getPriority).max().orElse(Integer.MIN_VALUE);
        List<MyPojo> maxPojos = list.stream().filter(pojo -> pojo.getPriority() == max).collect(Collectors.toList());
    }
}
IQbrod
  • 2,060
  • 1
  • 6
  • 28
  • Thank you. This loops twice through the list. Is there a way to solve this with Java streams by first grouping and then getting the first (highest) group? This should be more efficient, I believe. –  Oct 12 '20 at 07:25
  • Look at @Lino's answer. – IQbrod Oct 12 '20 at 07:27
2

You can do this using a TreeMap and the Collectors.groupingBy():

TreeMap<Integer, List<MyPojo>> map = pojos.stream()
                                          .collect(Collectors.groupingBy(
                                              MyPojo::getPriority, 
                                              TreeMap::new, 
                                              Collectors.toList()
                                           ));

List<MyPojo> maxPrios = map.lastEntry().getValue();

The lastEntry() will return the pojos with the highest priority, due to the natural ordering of Integers where the smallest value will be first, and the largest value will be last.

Lino
  • 19,604
  • 6
  • 47
  • 65