Java Stream:查找具有最小/最大值属性的元素 [英] Java Stream: find an element with a min/max value of an attribute

查看:21
本文介绍了Java Stream:查找具有最小/最大值属性的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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);

但是,我一直无法在 Stream API 中找到匹配的方法.这让我感到惊讶,因为通过属性查找最小值/最大值似乎是一种常见模式.我想知道是否有比使用比较器更好的方法(除了 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:

有一个通用的cache方法:

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<>());
}

这可以如下使用:

String coolestString = stringList
        .stream()
        .max(Comparator.comparing(cache(CoolUtil::coolnessIndex)))
        .orElse(null);

这篇关于Java Stream:查找具有最小/最大值属性的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆