在Something like 'contains any' for Java set?中有几种解决方案
我的情况是set1是new ConcurrentHashMap<>().keySet()
,set2是ArrayList
set1最多可以包含100个条目,set2少于10个条目
还是会全部一样做并且表现相似?
答案 0 :(得分:2)
public static void main(String[] args) {
Map<String, String> map = new ConcurrentHashMap<>();
List<String> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
map.put(RandomStringUtils.randomNumeric(5), RandomStringUtils.randomNumeric(5));
}
for (int i = 0; i < 10; i++) {
list.add(RandomStringUtils.randomNumeric(5));
}
Set<String> set = new HashSet<>(list);
List<Runnable> methods = new ArrayList<>();
methods.add(() -> { Collections.disjoint(map.keySet(), list); });
methods.add(() -> { Collections.disjoint(list, map.keySet()); });
methods.add(() -> { map.keySet().stream().anyMatch(list::contains); });
methods.add(() -> { list.stream().anyMatch(map.keySet()::contains); });
methods.add(() -> { Sets.intersection(map.keySet(), set).isEmpty(); });
methods.add(() -> { Sets.intersection(set, map.keySet()).isEmpty(); });
methods.add(() -> { CollectionUtils.containsAny(map.keySet(), list); });
methods.add(() -> { CollectionUtils.containsAny(list, map.keySet()); });
for (Runnable method : methods) {
long start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
method.run();
}
long end = System.currentTimeMillis();
System.out.println("took " + (end - start));
}
}
获奖者iiis Collections.disjoint
took 15
took 32
took 484
took 62
took 157
took 47
took 24
took 32
答案 1 :(得分:1)
setA.stream().anyMatch(setB::contains)
最好,因为所有其他选项都是非延迟评估,并且将在所有元素上执行。
对于流,它将是惰性计算,一旦找到任何匹配项,就会返回。
另外,来自Documentation of CollectionUtils.containsAny()
换句话说,如果coll1和coll2的交集(java.lang.Iterable,java.lang.Iterable)不为空,则此方法返回true。