2012-08-27 45 views
6

我看到的Java哈希表,明確方法,像這樣:
看不慣實現HashMap的明確方法在Java中

public void clear() { 
    modCount++; 
    Entry[] tab = table; 
    for (int i = 0; i < tab.length; i++) 
     tab[i] = null; 
    size = 0; 
} 

我不明白,爲什麼採取新的選項卡,清除。

爲什麼不使用表來清除?

+1

可能爲了可讀性。 –

回答

4

我不明白,爲什麼新標籤要清除。

這不是一個新表...它只是一個局部變量。

我能想到的三種可能原因:

  • 可讀性,通過@Bhesh古龍的建議......雖然它很難讓這裏(IMO)的差異。

  • 如果一個線程調用clear()而第二個線程執行可能導致表擴展的更新,則可能會減輕(稍微)造成的損害。但它當然不能解決這個問題,所以我傾向於將此視爲無稽之談。

  • 它可能會提高性能;例如因爲優化器知道局部變量tab中的引用不能更改,所以它可以更好地優化數組邊界檢查。

其中,我認爲第三個原因是最合理的。

(我不認爲這是什麼做的transient修改。在這種情況下,修改只針對有可讀性。在HashMap類提供readObjectwriteObject這使得transient修改實際意義的。)

2

這可能是因爲table字段被聲明爲transient,因此它不是HashMap對象的持久狀態的一部分。 table字段在諸如resize()之類的方法中被替換,因爲字段在遍歷clear()方法調用中的所有條目時可能會從下方交換。如果首先參考table並重復遍歷該參考,我們保證如果table字段發生變化,我們仍然會遍歷原始的table

+0

但是'HashMap'在「正常」操作中不是線程安全的,那麼它爲什麼會在'clear()'中關心它呢? –

+0

@JoachimSauer如果在一個線程中添加更多條目,它會在另一個線程調用clear()後調用'resize()'。這樣做可以確保'clear()'調用將所有舊條目設置爲空,而新的'table'正在創建。否則,在最壞的情況下,除了我剛剛添加的條目外,我最終可能會得到所有空值的HashMap。 –

+0

我明白什麼是好的線程安全。但是我說的是:單獨放置不是線程安全的(如果多線程調用它,會發生令人討厭的事情)。那麼爲什麼他們會關心其他方法是否是線程安全的呢? –