如果我在这里遗漏了一些核心 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)。
' HashMapscontainsKey(Object key)主要是给你O(1)复杂性。但是,containsAll()确实会遍历n元素。您的最坏情况复杂性变为O(n).
我之所以说它主要是因为 a 的性能HashMap依赖于散列。
添加回答
举报
0/150
提交
取消
