作者热门文章
- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个需求,检查两个列表中是否有共同的元素。我想出了两种方法来做到这一点:
方法 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/
我是一名优秀的程序员,十分优秀!