关于AbstractCollection实现

时间:2014-06-21 11:51:44

标签: java list collections

我看过abstraccollection并发现 containsAll 方法遍历整个集合。 为什么这种方法不检查集合的大小?如果主集合只有一个元素而目标集合有100000个元素,则性能会降低。

ArrayList还有重写方法isEmpty,用于比较列表的大小和0.为什么这个方法被覆盖并用这样的实现覆盖? AbstractCollection的实现几乎相同。

非常感谢

2 个答案:

答案 0 :(得分:3)

它不会检查集合的大小,因为大小不必相同。

如果一个列表中包含重复元素,containsAll仍然可以返回true:

AbstractCollection<Integer> first = new ArrayList<>();
AbstractCollection<Integer> second = new ArrayList<>();
first.add(1);
second.add(1);
second.add(1);

System.out.println(first.containsAll(second)); // Prints 'true'

要弄清楚为什么isEmpty被实现,你可能不得不问问制作它的开发人员。可能是他们希望避免调用size()的开销,以防编译器没有内联。


编辑:Shail016已经解决了这些问题,但无论如何我想将它们添加到我的答案中。

  

1)如果第一个集合根本没有任何元素

,该怎么办?

如果它没有任何元素containsAll将在第一次contains检查时返回false(它不会进行任何不必要的迭代),因此检查大小0不会&#39 ; t会产生很大的不同(它会为containsAll的所有用途添加额外的比较)。因此,这种检查可能被认为是不必要的。

  

2)为什么HashSet依赖于父方法?

它没有。它依赖于内部isEmpty的{​​{1}}。

HashMap

public boolean isEmpty() { return map.isEmpty(); } 的实施与HashMap

中的实施相同

答案 1 :(得分:1)

MAV是正确的:

检查AbstractCollection源代码中的containsAll()也告诉它不需要进行大小检查:

  public boolean containsAll(Collection<?> c) {
        for (Object e : c)
            if (!contains(e))//here its sort of size proof, also check indexOf in ArrayList
                return false;
        return true;
    }

The method returns on the very first check failure.(两个列表之间的大小差异或第一个非现有值)

另外,hashset不依赖于parents方法,而是依赖于isEmpty支持HashMap(它再次覆盖isEmpty,如ArrayList)