Java Stream:查找具有属性的最小/最大值的元素 [英] Java Stream: find an element with a min/max value of an attribute
问题描述
我有一个对象流,我想找到一个具有某些属性的最大值的计算器。
I have a stream of objects and I would like to find the one with a maximal value of some attribute that's expensive to calculate.
作为一个特定的简单示例,假设我们有一个字符串列表,我们希望找到最酷的字符串,给定 coolnessIndex
函数。
As a specific simple example, say that we have a list of strings and we want to find the coolest one, given a coolnessIndex
function.
以下应该有效:
String coolestString = stringList
.stream()
.max((s1, s2) -> Integer.compare(coolnessIndex(s1), coolnessIndex(s2)))
.orElse(null);
现在,这有两个问题。首先,假设 coolnessIndex
的计算成本很高,这可能不会非常有效。我想 max
方法需要重复使用比较器,这反过来会反复调用 coolnessIndex
对于每个字符串,它将被多次调用。
Now, there are two problems with this. First, assuming the coolnessIndex
is expensive to calculate, this probably won't be very efficient. I suppose the max
method will need to use the comparator repeatedly, which in turn will call the coolnessIndex
repeatedly and at the end it will be called more than once for each string.
其次,必须提供比较器会导致代码中出现一些冗余。我更喜欢这样的语法:
Second, having to provide the comparator leads to some redundancy in the code. I would much prefer syntax like this:
String coolestString = stringList
.stream()
.maxByAttribute(s -> coolnessIndex(s))
.orElse(null);
但是,我无法在中找到匹配的方法流
API。这让我感到惊讶,因为通过属性查找min / max似乎是一种常见的模式。我想知道是否有比使用比较器更好的方法(除了for循环)。
However, I haven't been able to find a matching method in the Stream
API. This surprises me, since finding min/max by an attribute seems like a common pattern. I wonder if there's a better way than using the comparator (other than a for loop).
推荐答案
谢谢大家的建议。最后我找到了我最喜欢的解决方案,在比较器工作方式的效率 - 来自bayou.io的答案:
Thanks everyone for suggestions. At last I found the solution I like the most at Efficiency of the way comparator works -- the answer from bayou.io:
具有通用缓存
方法:
public static <K,V> Function<K,V> cache(Function<K,V> f, Map<K,V> cache)
{
return k -> cache.computeIfAbsent(k, f);
}
public static <K,V> Function<K,V> cache(Function<K,V> f)
{
return cache(f, new IdentityHashMap<>());
}
然后可以按如下方式使用:
This could then be used as follows:
String coolestString = stringList
.stream()
.max(Comparator.comparing(cache(CoolUtil::coolnessIndex)))
.orElse(null);
这篇关于Java Stream:查找具有属性的最小/最大值的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!