2011-11-08 17 views
8

我需要將一些數據與其生命週期中的某個關鍵字相關聯,所以我使用的是WeakHashMap。但是,另外我需要通過相應的值獲取密鑰。最簡單的方式做到這一點是建立一個值時,扶住參考:如果該值包含唯一對該密鑰的強引用,是否會收集WeakHashMap的條目?

public class Key {} 

public class Value { 
    final public Key key; 
    public Value(Key k) { 
     key = k; 
    } 
} 

當然,雖然我在程序中使用Value,其key不會消失。但是,如果在地圖之外沒有更多關鍵字或其值的引用,它是否會被垃圾收集?還是值得生存的強有力的參考預防呢?

回答

13

沒有也不會被垃圾收集,看到Javadoc

實現注意事項:WeakHashMap中的值對象由普通的強引用舉行。因此,應該注意確保值對象不直接或間接強烈地引用它們自己的密鑰,因爲這將防止密鑰被丟棄。

正如@biziclop所提到的,解決方案之一是在您的值對象中存儲對鍵的弱引用。

public class Value { 
    final public WeakReference<Key> key; 
    public Value(Key k) { 
    this.key = new WeakReference<Key>(k); 
    } 
} 
+1

+1也許我應該先閱讀文檔。 :) – biziclop

+0

@biziclop同樣來自Javadoc:處理這個問題的一種方法是在插入之前將值本身包含在WeakReferences中,如:m.put(key,new WeakReference(value)),然後展開每個get。 這應該做的伎倆! – laguille

+0

要麼只是存儲對值對象中的鍵的弱引用。因爲如果將值包含在WR中,則最終可能會收集一個已收集值爲al的值的現有密鑰。 – biziclop

2

看着實現,答案似乎是否定的。

這是從WeakHashMap來源:

/** 
* The table, resized as necessary. Length MUST Always be a power of two. 
*/ 
private Entry[] table; 

... 

private static class Entry<K,V> extends WeakReference<K> implements Map.Entry<K,V> { 
    private V value; 
    ... 
} 

正如你所看到的,Entry對象是強由地圖本身引用。所以如果地圖可以訪問,那麼Entry,因此你的Value對象,你的鑰匙也是。

相關問題