如果我在这里遗漏了一些核心 Java,请原谅我。我正在通过HashSet's javadocs 搜索它的实现规范,Collection.containsAll()它显然继承了AbstractCollection根据JDK 8 源代码文档的实现,如下所示:public boolean containsAll(Collection<?> c) { for (Object e : c) if (!contains(e)) return false; return true;}我的问题源于这样一个事实,即虽然HashSet不会覆盖containsAll()它但是会覆盖contains():public boolean contains(Object o) { return map.containsKey(o);}AbstractCollection同样地:public boolean contains(Object o) { Iterator<E> it = iterator(); if (o==null) { while (it.hasNext()) if (it.next()==null) return true; } else { while (it.hasNext()) if (o.equals(it.next())) return true; } return false;}我的理解是,当实例成员调用未在实例中明确指定时,JVM 会隐式替换它this.instanceMemberCall(),在这种情况下将转换为AbstractCollection'contains()被调用。但是我再次在这里读到HashMap/的时间复杂度将是 O(n),这表明's HashSet( O(1)) 被调用。希望能清楚地了解这背后的实际语义是什么。containsAll()HashSetcontains()
2 回答
阿波罗的战车
TA贡献1862条经验 获得超6个赞
不,这只是多态性。每当在对象上调用方法时,该对象的真实类型很重要,仅此而已。
foo()
含义:在 Base 中实现并不重要。当在 Child 中被覆盖时foo()
调用。当你有一个 Child 对象时,它总是会被调用的 Child 版本。bar()
bar()
bar()
在您的示例中,this
不是 AbstractSet,它是HashSet
!
或者换句话说:调用方法的“位置”并不重要。重要的是调用它的对象的类型。如前所述,您的对象是 HashSet 类型!
慕码人8056858
TA贡献1803条经验 获得超6个赞
这是个有趣的问题。HashSet
在 Java 中由HashMap
. 该containsAll()
方法只是contains()
在这种情况下HashSet
的 contains 方法中循环。那是因为HashSet
覆盖了contains
和委托。
因为HashSet
由HashMap
实际调用支持 is containsKey(Object key)
。
' HashMap
scontainsKey(Object key)
主要是给你O(1)
复杂性。但是,containsAll()
确实会遍历n
元素。您的最坏情况复杂性变为O(n)
.
我之所以说它主要是因为 a 的性能HashMap
依赖于散列。
添加回答
举报
0/150
提交
取消