我想比较a中的任何对象list2
是否存在于a中list1
.
我可以遍历两个列表并比较所有元素,.contains()
但我想知道是否有更有效的方法.我找到了这个,我正在尝试实现建议的方法:
List<Item> list1;
List<Item> list2;
boolean anyMatch = list1.stream().anyMatch(x -> x.equals(list2.stream()));
System.out.println(anyMatch);
Run Code Online (Sandbox Code Playgroud)
当我这样做false
时,我会不断地得到,即使在我期待的时候true
.怎么会?
Tun*_*aki 11
根据您的评论,您有两个列表,list1
和list2
.你想,如果在元件的至少一个,找出list2
包含在list1
.
随着流API,你可以获取Stream
的list2
.然后,调用anyMatch(predicate)
返回此流的一个元素是否与给定谓词匹配,在这种情况下,测试是否包含该元素list1
.
boolean anyMatch = list2.stream().anyMatch(list1::contains);
Run Code Online (Sandbox Code Playgroud)
这使用方法引用作为谓词.
通过转换list1
为a 可以获得更好的性能Set
,从而保证了恒定时间的查找:
boolean anyMatch = list2.stream().anyMatch(new HashSet<>(list1)::contains);
Run Code Online (Sandbox Code Playgroud)
虽然@Tinaki的答案是正确的,但这是另一种更简洁的方法(Stream.anyMatch()
尽管它不使用方法):
boolean anyMatch = !Collections.disjoint(list1, list2);
Run Code Online (Sandbox Code Playgroud)
这使用了该Collections.disjoint()
方法,true
当两个集合没有共同的元素时返回.
Tunaki关于性能的评论也适用于此:为了获得更好的性能,最好将你list1
变成a HashSet
,因为它的contains()
方法是O(1)
平均的.该Collections.disjoint()
方法实际上检查它的任何参数是否为a Set
并迭代不是a的集合Set
.所以在你的情况下,你所要做的就是HashSet
从你的list1
:创建一个:
boolean anyMatch = !Collections.disjoint(new HashSet<>(list1), list2);
Run Code Online (Sandbox Code Playgroud)
注意:毕竟,我的答案只比Tunaki的短了5个字符:)
boolean isAnyMatch = list2.stream().anyMatch(list1::contains);
Run Code Online (Sandbox Code Playgroud)
boolean isAnyMatch = !Collections.disjoint(new HashSet(list1), list2);
Run Code Online (Sandbox Code Playgroud)
无论如何,在比较之前将列表转换为设置将提供更快的输出。