Java 流:查找具有属性的最小/最大值的元素

2022-09-01 09:05:15

我有一个对象流,我想找到一个具有某些属性最大值的对象,该属性的计算成本很高。

作为一个特定的简单示例,假设我们有一个字符串列表,并且我们希望找到给定函数的最酷的字符串。coolnessIndex

以下方法应该有效:

String coolestString = stringList
        .stream()
        .max((s1, s2) -> Integer.compare(coolnessIndex(s1), coolnessIndex(s2)))
        .orElse(null);

现在,这有两个问题。首先,假设计算成本很高,这可能不是很有效。我想该方法需要重复使用比较器,而比较器又会重复调用,最后将为每个字符串调用多次。coolnessIndexmaxcoolnessIndex

其次,必须提供比较器会导致代码中的一些冗余。我更喜欢这样的语法:

String coolestString = stringList
        .stream()
        .maxByAttribute(s -> coolnessIndex(s))
        .orElse(null);

但是,我无法在API中找到匹配的方法。这让我感到惊讶,因为通过属性查找最小值/最大值似乎是一种常见的模式。我想知道是否有比使用比较器更好的方法(除了for循环)。Stream


答案 1
Stream<String> stringStream = stringList.stream();
String coolest = stringStream.reduce((a,b)-> 
    coolnessIndex(a) > coolnessIndex(b) ? a:b;
).get()

答案 2

这是一个使用 a 作为元组的变体,不是最漂亮的代码,而是简洁Object[]

String coolestString = stringList
        .stream()
        .map(s -> new Object[] {s, coolnessIndex(s)})
        .max(Comparator.comparingInt(a -> (int)a[1]))
        .map(a -> (String)a[0])
        .orElse(null);