3 回答

TA貢獻(xiàn)1780條經(jīng)驗 獲得超1個贊
嘗試使用Integer
對象作為 a 的鍵WeakHashMap
可能會導(dǎo)致一些奇怪的行為。首先,javadoc forWeakHashMap
有以下注釋:
此類主要用于其等于方法使用 == 運算符測試對象身份的關(guān)鍵對象。一旦這樣的鍵被丟棄,它就永遠(yuǎn)不會被重新創(chuàng)建,所以以后不可能在 WeakHashMap 中查找該鍵,并且會驚訝于它的條目已被刪除。此類將與關(guān)鍵對象完美配合,這些對象的 equals 方法不基于對象標(biāo)識,例如 String 實例。然而,對于這種可重新創(chuàng)建的鍵對象,自動刪除鍵已被丟棄的 WeakHashMap 條目可能會令人困惑。
考慮以下代碼:
WeakHashMap<Integer, String> map = new WeakHashMap<>();
Integer k = Integer.valueOf(9001);
map.put(k, "OVER 9000!?");
while (true)
{
System.out.println(map.get(k));
Thread.sleep(100);
k = Integer.valueOf(9001);
System.gc();
}
循環(huán)將從打印“OVER 9000!?”開始,但在第一個循環(huán)之后,原始鍵已被丟棄(即使現(xiàn)在有一個equals對它的鍵的引用)。結(jié)果,如果該鍵對象被垃圾收集,則條目將從地圖中刪除,并且循環(huán)將開始打印“null”。由于我們System.gc();在丟棄密鑰后調(diào)用,因此這很可能發(fā)生在單個循環(huán)之后。
但這并不是Integer作為WeakHashMap密鑰使用的問題的結(jié)束。如果將上面的值 9001 更改為 1,您會發(fā)現(xiàn)行為發(fā)生了變化?。赡??這可能取決于實現(xiàn)。)現(xiàn)在,條目永遠(yuǎn)不會從地圖中刪除。這是因為整數(shù)緩存——Integer.valueOf(1)總是返回相同的Integer實例,但每次都會Integer.valueOf(9001)創(chuàng)建一個新Integer實例。
第二個問題特定于Integer,但第一個問題實際上適用于您嘗試在equals不基于 的情況下使用密鑰的任何方案==。如果equals 是基于==,那么你的問題并沒有真正適用-如果你沒有很強的參考鑰匙了,也不要緊,是否值被從地圖上刪除,因為你不再有辦法得到它——你不能重新創(chuàng)建一個使用基于身份的平等的密鑰。
添加回答
舉報