【问题标题】:Comparing two collections using Stream - anyMatch使用 Stream 比较两个集合 - anyMatch
【发布时间】:2016-04-16 22:34:00
【问题描述】:

我想比较list2 中的任何对象是否存在于list1 中。

我可以遍历这两个列表并使用.contains() 比较所有元素,但我想知道是否没有更有效的方法。我找到了this,我正在尝试实施建议的方法:

List<Item> list1;
List<Item> list2;

boolean anyMatch = list1.stream().anyMatch(x -> x.equals(list2.stream()));
System.out.println(anyMatch);

当我这样做时,我不断得到false,即使我期望得到true。怎么会?

【问题讨论】:

  • Steam 有很多脚手架来保持惰性评估的状态。
  • 您正在将 list1 中的元素与 list2 的流进行比较。它们甚至不是同一类型。使用流不会让任何事情变得更快。您可以使用 list1.equals(list2) 但顺序很重要。如果顺序无关紧要并且项目是唯一的,请使用 Set 而不是 List。
  • @Tunaki 应该是列表,我的错。我想比较 list2 中的任何对象是否存在于 list1 中。应该更清楚。
  • 你将如何通过迭代来做到这一点?举个例子,让我们更清楚地理解。

标签: java java-stream


【解决方案1】:

在您的 cmets 中,您有两个列表,list1list2。您想查明list2 中的至少一个元素是否包含在list1 中。

使用 Stream API,您可以获得list2Stream。然后,调用anyMatch(predicate) 返回此流的元素之一是否与给定谓词匹配,在这种情况下,它会测试该元素是否包含在list1 中。

boolean anyMatch = list2.stream().anyMatch(list1::contains);

这使用method reference 作为谓词。

通过将list1 转换为Set,您将获得更好的性能,这保证了恒定时间查找:

boolean anyMatch = list2.stream().anyMatch(new HashSet<>(list1)::contains);

【讨论】:

  • 正是我想要的。谢谢!
【解决方案2】:

虽然@Tunaki's answer 是正确的,但这里有另一种更简洁的方法(虽然它不使用Stream.anyMatch() 方法):

boolean anyMatch = !Collections.disjoint(list1, list2);

这使用Collections.disjoint() 方法,当两个集合没有共同的元素时返回true

Tunaki 关于性能的评论也适用于这里:为了获得更好的性能,最好将您的list1 变成HashSet,因为它的contains() 方法是O(1) 平均值。 Collections.disjoint() 方法实际上检查它的任何参数是否为Set 并遍历不是Set 的集合。所以在你的情况下,你所要做的就是从你的list1创建一个HashSet

boolean anyMatch = !Collections.disjoint(new HashSet<>(list1), list2);

注意:毕竟,我的答案只比 Tunaki 的短 5 个字符 :)

【讨论】:

  • 感谢您展示实现此目的的另一种方法。如果我将列表转换为HashSet,我认为这两种方法具有相同的性能?
  • @k88 如果流是顺序的,它们具有相同的性能。如果它是并行的,那么当列表有很多元素时它会表现得更好(几千或更多,你必须测试它,取决于机器)。此外,为了获得最佳性能,您应该将具有更多元素的列表转换为 HashSet 并迭代另一个。
【解决方案3】:
  • 使用 Java 8 流 api
boolean isAnyMatch = list2.stream().anyMatch(list1::contains);
  • 使用 Collection 类方法
boolean isAnyMatch = !Collections.disjoint(new HashSet(list1), list2);

在比较之前将列表转换为设置将提供更快的输出。

【讨论】:

    猜你喜欢
    • 2014-12-10
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多