我看过abstraccollection并发现 containsAll 方法遍历整个集合。 为什么这种方法不检查集合的大小?如果主集合只有一个元素而目标集合有100000个元素,则性能会降低。
ArrayList还有重写方法isEmpty,用于比较列表的大小和0.为什么这个方法被覆盖并用这样的实现覆盖? AbstractCollection的实现几乎相同。
非常感谢
答案 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)