如果我在這里遺漏了一些核心 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
提交
取消