java - 使用 lambda 表达式是否可以提高性能?

标签 java performance lambda

我有一个需求,检查两个列表中是否有共同的元素。我想出了两种方法来做到这一点:

方法 01:循环

private boolean func01 (List<String> list1, List<String> list2) {
    for (String group : list1) {
        for (String funcGroup : list2) {
            if (group.equals(funcGroup)) {
                return true;
            }
        }
    }
    return false;
}

方法 02:Lambda

private boolean func02 (List<String> list1, List<String> list2) {
    return list1.stream().filter(list2::contains).findAny().isPresent();
}

在我看来,我发现第一种方法更具可读性。我需要了解的是,比较这两种方法时,是否有任何差异或优势?

最佳答案

方法一优化:

你不需要 2 个循环,当你有一个匹配时你可以立即返回,所以你在那个点停止遍历列表 - (例如阳光情况下你在第一个元素上得到匹配 - 你有 1 次迭代,最坏的情况是你的匹配项是最后一个元素——你必须遍历整个列表才能匹配到该匹配项)

private boolean func01 (List<String> list1, List<String> list2) {
        for (String group : list1) {
            if (list2.contains(group)) return true;
        }

        return false;
    }

lambda 等效优化:

  • findAny().isPresent() - 获取与谓词匹配的元素的可选项,并检查是否存在可选项 - 这相当于 anyMatch()因为两个表达式都返回 boolean

  • filter()总会遍历整个列表

  • anyMatch()具有短路行为 - 意味着它将在第一场比赛中停止

因此您可以将其重写为:

private boolean func02 (List<String> list1, List<String> list2) {
  return list1.stream().anyMatch(list2::contains);
}

回答您的问题 - 这两种方法在性能上没有显着差异,请考虑:

  • 为集合创建流的开销很小

  • 流操作可以并行运行 (list1.stream().parallel().anyMatch(list2::contains))。例如,在这种情况下,anyMatch() 在同一流上的并行线程中运行,将定期检查先前的线程是否找到匹配项,并将停止遍历集合而不是继续遍历整个集合。因此理论上对于非常大的输入列表,您应该使用并行流获得更好的结果。

关于java - 使用 lambda 表达式是否可以提高性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49642494/

相关文章:

c# - 委托(delegate)创建的性能不足

performance - Excel 列表对象 VBA 性能错误?

Java 8 : Stream a list and map to another list based on different filters

function - C++11 : easiest way to create a function always returning true to use for a function argument

java - 扩大冗长 Activity 序列的最佳方法是什么?

java - Jetty 服务器总是使用处理程序返回 404

java - JsonView 无法与 Spring 一起正常工作

java - 使用 .java 文件编译文件夹并将其打包

python - 调用对象的状态特定代码块的最有效方法是什么?

c# - 如何使用 lambda 表达式来过滤数据行?