进行containsAny检查的最快方法是什么?

时间:2019-10-10 10:01:28

标签: java

Something like 'contains any' for Java set?中有几种解决方案

  • Collections.disjoint(A,B)
  • setA.stream()。anyMatch(setB :: contains)
  • Sets.intersection(set1,set2).isEmpty()
  • CollectionUtils.containsAny()

我的情况是set1是new ConcurrentHashMap<>().keySet(),set2是ArrayList

set1最多可以包含100个条目,set2少于10个条目

还是会全部一样做并且表现相似?

2 个答案:

答案 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。