java - 具有昂贵的自定义键功能的列表的最大值

标签 java collections java-8 max comparator

在 Java 中查找您编写的序列的最大元素:

GameState bestGs = Collections.max(ns,
        Comparator.comparing(e -> minimax(e)));

这里的minimax是一个返回数字的函数,ns是一个集合。该代码有效,但将为集合中的每个元素多次评估键函数。我该怎么做才能使每个元素只评估一次?在 Python 中,您只需编写 max(seq, key = lambda e: minimax(e))Java 中一定有类似的东西吗?别让我自己写 forloop,现在是 21 世纪我不应该写!

显式循环代码如下:

GameState best = null;
// Doesn't matter what scalar type is used.
int bestScore = Integer.MIN_VALUE;  
for (GameState n : ns) {
    int thisScore = minimax(n);
    if (thisScore > bestScore) {
        bestScore = thisScore;
        best = n;
    }
}

我想用 Java 以“函数式”的方式编写上面的代码,但又要保留高性能。

最佳答案

你可以 memoize e -> minimax(e) 函数:

public static <T, S> Function<T, S> memoize(Function<T, S> function) {
    Map<T, S> cache = new HashMap<>();
    return argument -> cache.computeIfAbsent(argument, function);
}

然后,只需使用 memoized 函数:

GameState bestGs = Collections.max(ns,
    Comparator.comparing(memoize(e -> minimax(e))));

编辑:此方法要求GameState 实现hashCodeequals一致 .这些方法也应该运行得非常快(这是通常的情况)。


编辑 2: 正如 M. Justin 在下面的评论中所说,此解决方案不是线程安全的。如果要从多个线程使用内存函数,则应使用 ConcurrentHashMap 而不是 HashMap

关于java - 具有昂贵的自定义键功能的列表的最大值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52517849/

相关文章:

java - 吝啬的链接结构和节点?

java - Android Fragment findViewById 在膨胀 View 后返回 Null

java - 通过build.gradle文件告诉IntelliJ为Javac设置-parameters标志

java - Spark MLlib 0.91 org.jblas.DoubleMatrix 错误

c# - C# 集合是值类型还是引用类型?

algorithm - 负载系数0.75是什么意思?

java - 如何使用 lambda 流迭代嵌套列表?

java - 有没有办法压缩两个流?

java - Tomcat 8 无法创建 Java jli.dll

Java客户端-服务器/单线程多客户端