我有一个对象流,我想找到一个具有某个属性的最大值的元素,它的计算开销很大。Java Stream:找到具有属性的最小值/最大值的元素
作为一个特定的简单例子,假设我们有一个字符串列表,并且我们想要找到最酷的一个,给定一个coolnessIndex
函数。
下面应该工作:
String coolestString = stringList
.stream()
.max((s1, s2) -> Integer.compare(coolnessIndex(s1), coolnessIndex(s2)))
.orElse(null);
现在,有两个问题。首先,假设coolnessIndex
计算起来很昂贵,这可能不会很有效。我想max
方法将需要重复使用比较器,这反过来将重复调用coolnessIndex
,并且最终将为每个字符串调用多次。
其次,必须提供比较器会导致代码中出现一些冗余。我更希望的语法是这样的:
String coolestString = stringList
.stream()
.maxByAttribute(s -> coolnessIndex(s))
.orElse(null);
但是,我一直没能找到Stream
API的匹配方法。这令我感到惊讶,因为通过属性查找min/max似乎是一种常见模式。我想知道是否有比使用比较器更好的方法(for循环除外)。
相关但不完全重复:http://stackoverflow.com/questions/27606185/arg-max-in-java-8-streams(其中关注是代码简洁而不是效率,我认为推荐的解决方案仍然最终会反复调用相同的'coolnessIndex')。 –
我不相信Java流API中有任何与此相当的东西。你可以实现你自己的'maxByAttribute'版本(别人已经完成了某些[这里](https://gist.github.com/mapio/57299694ef94cc88dddb),但我没有看过他们的代码),或者你可以使用'map'来获得一串对('s','coolnessIndex(s)'),然后是'max' - 但是AIUI Java没有一个方便的pair类,所以你最终会得到一个很多样板代码,更不用说所有额外的内存分配。 –
您可以通过字符串 - >凉爽结果进行分组,然后选择最酷的字符串。请参阅https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toMap-java.util.function.Function-java.util.function.Function- –