2013-05-31 30 views
1

相同的密鑰根據Java文檔weakhashmap重新創建上WeakHashMap中

「這個類的對象主要是與主要對象,它們的equals方法測試使用==運算對象標識使用一旦這樣的密鑰將被丟棄它不能被重新創建,所以不可能在WeakHashMap中查找該密鑰「

這是否意味着如果我們使用objectA作爲弱哈希映射中條目0的鍵,並且稍後我們移除該條目testMapHashWeak.remove(objectA);我們無法爲另一個條目使用相同的密鑰objectA?因爲我做了一個小測試,我可以做到這一點:

public void test4WeakHashMap(WeakHashMap<B, String> testMapHashWeak) { 
    B objectB = new B(); 
    String sTest = "hola"; 
    System.out.println("1st time - key&value inserted ->"+objectB+","+sTest); 
    testMapHashWeak.put(objectB, sTest); 
    System.out.println("Get element 1st time-> "+testMapHashWeak.get(objectB)); 
    testMapHashWeak.remove(objectB); 
    //Insert 2nd time 
    System.out.println("2st time - key&value inserted ->"+objectB+","+sTest); 
    testMapHashWeak.put(objectB, sTest);   
    System.out.println("Get element 2nd time-> "+testMapHashWeak.get(objectB)); 
} 

作爲輸出:在句子

1st time - key&value inserted ->[email protected],hola 
Get element 1st time-> hola 
2st time - key&value inserted ->[email protected],hola 
Get element 2nd time-> hola 

回答

1

的描述:

這個類的對象主要是與主要對象,它們的使用 equals方法測試使用==運算對象的身份。一旦 這種密鑰將被丟棄它可以永遠不會被重新創建,所以不可能 做鍵的查找WeakHashMap中

意味着這個類的目的是與鍵使用,其娛樂後(產生新的完全相同的實例)在相互比較時返回假。換句話說,這樣的密鑰的每個新實例將是唯一的(只有在使用equals()與自身比較時返回true,並且與任何其他實例/對象比較時返回錯誤)例如String不是這樣的類,而Object是:

WeakHashMap testMapHashWeak = new WeakHashMap<Object, String>(); 

String value1 = "Hola1!"; 
String value2 = "Hola2!"; 

String key1 = new String("key"); 
String key2 = new String("key"); 

assert key1 != key2; // Keys are different objects... 
assert key1.equals(key2); // but are equal to each other 

testMapHashWeak.put(key1, value1); 
testMapHashWeak.put(key2, value2); 

// value2 instead of value1! 
System.out.println("Get using key1 (expected Hola1): "+testMapHashWeak.get(key1)); 
// value2 
System.out.println("Get using key2 (expected Hola2): "+testMapHashWeak.get(key2)); 

Object key3 = new Object(); 
Object key4 = new Object(); 

assert key3 != key4; // Keys are different objects... 
assert !key3.equals(key4); // and are not equal to each other 

testMapHashWeak.put(key3, value1); 
testMapHashWeak.put(key4, value2); 

// value2 instead of value1! 
System.out.println("Get using key3 (expected Hola1):"+testMapHashWeak.get(key3)); // value1! 
// value2 
System.out.println("Get using key4 (expected Hola2):"+testMapHashWeak.get(key4)); 

WeakHashMap是具有弱密鑰的Map的實現。所以在密鑰被垃圾收集之後,地圖中的整個條目(鍵,值)將會消失。那麼這裏的關鍵詞是「之後」,這意味着不會更快。因此,鍵之間被標記爲'要被GC刪除',並且在它被實際刪除之前,映射將包含不可能獲得的鍵值條目。在使用基於字符串的鍵的第一個示例中,可以使用不同的鍵獲取值,但無法預測該值是否存在(可能已經是GCd)。在第二個例子中,無論如何你都不能。

+0

你的陳述是正確的,但你的榜樣不是。問題是包含字符串常量'「key」'*的key1和key2是*相同的實例(使用斷言很好,運行帶有斷言的代碼更好)。 Java使用相同的對象實例來表示編譯時常量字符串。用'new String(「key」)替換其中的一個將會創建不同的String實例相同的期望情況。 – Holger

+0

編輯代碼示例來建議修復。 – Holger

+0

雖然原始代碼已損壞,但編輯被拒絕;我不明白原因,因爲我建議的修復保持了原意。但是:除了第一個斷言失敗之外,創建對象key3和key4之後的斷言肯定應該引用它們而不是key1和key2。看來,只有原始的海報纔有可能修復該代碼。 – Holger

1

「丟棄」的意思是「重點對象不再在普通使用」 ,不再是一個活的對象。您的objectB不適用於整個範圍test4WeakHashMap方法。

從同一個文檔:

時,其關鍵是在普通使用不再WeakHashMap中的條目將自動被刪除。更準確地說,給定鍵的映射的存在不會阻止垃圾收集器丟棄該鍵,也就是說,該鍵被終止,完成並且然後被回收。當一個鍵被丟棄時,它的入口被有效地從地圖上移除,所以這個類的行爲與其他Map實現有些不同。

請注意「被垃圾回收器丟棄」。因此,「從地圖上移除」與「丟棄」不同。