如何使用流获取具有多个属性的最大值的对象?

MWB*_*MWB 3 java dry java-stream

说我有一堆恶棍.它们的特点是它们有多好,坏或难看.

static class Villain {
    String name;
    int good;
    int bad;
    int ugly;

    Villain(String name, int good, int bad, int ugly) {
        this.name = name;
        this.good = good;
        this.bad = bad;
        this.ugly = ugly;
    }
}
Run Code Online (Sandbox Code Playgroud)

好的,遇到帮派:

List<Villain> villains = new ArrayList<>();
villains.add(new Villain("Bob", 2, 2, 1));
villains.add(new Villain("Charley", 2, 1, 2));
villains.add(new Villain("Dave", 2, 1, 1));
villains.add(new Villain("Andy", 2, 2, 2));
villains.add(new Villain("Eddy", 1, 2, 2));
villains.add(new Villain("Franz", 1, 2, 1));
villains.add(new Villain("Guy", 1, 1, 2));
villains.add(new Villain("Harry", 1, 1, 1));
Run Code Online (Sandbox Code Playgroud)

我想做的是,我想弄清楚谁是最好的,最坏的和最丑的.我的意思是找出谁是最好的.如果出现平局,谁是最差的.在平局的情况下,谁是最丑陋的.

我已经成功地使用下面的代码.

List<Villain> bestVillains = villains
        .stream()
        .collect(groupingBy(v -> v.good, TreeMap::new, toList()))
        .lastEntry()
        .getValue()
        .stream()
        .collect(groupingBy(v -> v.bad, TreeMap::new, toList()))
        .lastEntry()
        .getValue()
        .stream()
        .collect(groupingBy(v -> v.ugly, TreeMap::new, toList()))
        .lastEntry()
        .getValue();
Run Code Online (Sandbox Code Playgroud)

事实上,这导致List<Villain>只有一个成员:安迪.他真的是最好的,最糟糕的,最丑陋的!

但是,我有相当多的代码重复,收集值,再次将它们变成流,等等.有关如何清理它的任何建议?

这是如何由JVM处理的.顺序还是引擎盖下面有一些神奇的东西?

Nam*_*man 5

因此,我们的想法是首先看看哪个具有最高价值,然后(如果是平局)具有最高价值,那么(如果它仍然不是决定性的)具有最高价值的'丑陋"

您更愿意使用以下内容ComparatorVillians 进行排序:

Comparator<Villain> villainComparator = Comparator.comparingInt(Villain::getGood)
    .thenComparingInt(Villain::getBad)
    .thenComparingInt(Villain::getUgly);

Villain result = villains.stream()
                         .max(villainComparator)
                         .orElse(null);
Run Code Online (Sandbox Code Playgroud)