回覆列表
  • 1 # 三僡然

    透過原始碼分析,應該是為了區別remove時是否成功

    每次將新鍵放入對映時,HashSet都不會新增新的Object。它確實使用了Object,但每次都使用相同的Object。該值在HashSetsource程式碼中命名為PRESENT。add方法在內部HashMap上呼叫put(key,PRESENT)。remove方法呼叫內部HashMap上的remove(key),但它必須返回一個布林值,指示該鍵是否存在。如果將null儲存為值,則HashSet需要先呼叫containsKey,然後刪除,以確定金鑰是否存在 - 額外的開銷。這裡,只有一個Object的記憶體開銷,這是非常小的。

  • 2 # 會點程式碼的大叔

    找到這個問題答案最簡單的方法,就是看一下原始碼,也順便了解一下HashSet其他方面的知識。

    開啟HashSet的原始碼,可以看到:

    首先可以看到,HashSet的底層實現,是基於HashMap的。

    private static final Object PRESENT = new Object();map = new HashMap<>();

    因為底層實現是HashMap,這也就理解了為什麼HashSet不允許重複。

    另外,很容易就發現我們需要找的內容:PRESENT

    private static final Object PRESENT = new Object();

    先看add()方法,可以發現插入到HashMap裡面的value是一個final的Object物件,而不是Null:

    最後,我們在remove方法裡面,可以找到我們需要的答案:

    由於HashSet的Remove實質就是HashMap的Remove,所以在看下HashMap的原始碼:

    想象一下,如果HashSet中底層的value存null的話,那麼當map.remove(o)==null的時候,是沒有辦法知道這個null究竟代表了什麼。

  • 中秋節和大豐收的關聯?
  • 夢見自己被人殺了,是怎麼回事?