Java 8 流 - .max() 与重复项

2022-09-01 20:55:57

因此,我有一个对象集合,其步骤变量可以是 1 - 4。

public class MyClass {
    private Long step;

    //other variables, getters, setters, etc.
}

Collection<MyClass> myOjbects = /*get collection*/;

然后,我想从集合中获取一个具有最大步长值的实例,因此我这样做:MyClass

final Optional<MyClass> objectWithMaxStep =
   myObjects.stream().max(Comparator.comparing(MyClass::getStep));

但是,在某些情况下,集合中将有多个实例的步长等于 4。MyClass

因此,我的问题是,如何确定在 中返回哪个实例,或者当流中的多个对象具有正在比较的最大值时,它是否会引发异常?Optional

该函数的 Java 8 文档未指定在此情况下将发生的情况。max()


答案 1

max实现减少集合:maxBy

 public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
    }

在这里,您可以看到当2个元素相等时,即 返回 0,然后返回第一个元素。因此,在您的情况下,将首先在具有最高 .comparator.compare(a, b) >= 0 ? a : bcompareMyClassstep

更新:正如用户the8472在评论中正确提到的那样,你不应该依赖javadocs没有明确指定的实现。但是你可以在方法上编写单元测试,以了解它在标准java库中的逻辑是否发生了变化。max


答案 2

由于文档未指定排序,因此在 JVM 的未来版本或 JVM 的不同实现中,顺序可能会有所不同。

如果您关心返回哪一个,那么我的建议是编写自己的缩减操作或收集器,以按照您的要求行事。这样,未来的实现就无法改变它,您可以明确说明将要发生的事情。


推荐