2013-09-23 47 views
6

在以下代碼示例中,如果將鍵設置爲null並調用System.gc(),則WeakHashMap會丟失所有映射並被清空。WeakHashMap vs HashMap

class WeakHashMapExample { 

public static void main(String[] args) { 

    Key k1 = new Key("Hello"); 
    Key k2 = new Key("World"); 
    Key k3 = new Key("Java"); 
    Key k4 = new Key("Programming"); 

    Map<Key, String> wm = new WeakHashMap<Key, String>(); 


    wm.put(k1, "Hello"); 
    wm.put(k2, "World"); 
    wm.put(k3, "Java"); 
    wm.put(k4, "Programming"); 
    k1=null; 
    k2=null; 
    k3=null; 
    k4=null; 
    System.gc(); 
    System.out.println("Weak Hash Map :"+wm.toString()); 

} 

} 

class Key{ 

private String key; 

public Key(String key) { 
    this.key=key; 
} 

@Override 
public boolean equals(Object obj) { 
    return this.key.equals((String)obj); 
} 
@Override 
public int hashCode() { 
    return key.hashCode(); 
} 
@Override 
public String toString() { 
    return key; 
} 

} 

Output: Weak Hash Map :{}

WeakHashMapHashMap一起使用和按鍵被設置爲null,則WeakHashMap不會失去它的鍵 - 值映射關係。

class WeakHashMapExample { 

public static void main(String[] args) { 

    Key k1 = new Key("Hello"); 
    Key k2 = new Key("World"); 
    Key k3 = new Key("Java"); 
    Key k4 = new Key("Programming"); 

    Map<Key, String> wm = new WeakHashMap<Key, String>(); 
    Map<Key, String> hm=new HashMap<Key, String>(); 

    wm.put(k1, "Hello"); 
    wm.put(k2, "World"); 
    wm.put(k3, "Java"); 
    wm.put(k4, "Programming"); 

    hm.put(k1, "Hello"); 
    hm.put(k2, "World"); 
    hm.put(k3, "Java"); 
    hm.put(k4, "Programming"); 
    k1=null; 
    k2=null; 
    k3=null; 
    k4=null; 
    System.gc(); 
    System.out.println("Weak Hash Map :"+wm.toString()); 
    System.out.println("Hash Map :"+hm.toString()); 
} 

} 

class Key{ 

private String key; 

public Key(String key) { 
    this.key=key; 
} 

@Override 
public boolean equals(Object obj) { 
    return this.key.equals((String)obj); 
} 
@Override 
public int hashCode() { 
    return key.hashCode(); 
} 
@Override 
public String toString() { 
    return key; 
} 

} 

輸出: Weak Hash Map :{Java=Java, Hello=Hello, World=World, Programming=Programming} Hash Map :{Programming=Programming, World=World, Java=Java, Hello=Hello}

我的問題是爲什麼不WeakHashMap失去其條目在第二個代碼示例的按鍵被丟棄後也?

回答

11

A WeakHashMap當密鑰不再可以直接從實時代碼獲得時丟棄條目。由於HashMap保持對密鑰的硬引用,所以密鑰仍可到達並且不會丟棄這些條目。

問題是,行爲必須與對關鍵對象的引用有關,而不是對可能同時具有對關鍵字的引用的任何變量的值。

+0

我甚至從來沒有想過變量只是包含一個指針,這是非常豐富的知道,謝謝! – xorinzor

2

對象對象必須在其他地方放棄,然後WeakHashMap清除該對象。像WeakReference一樣,它的目的是記住一個對象是否仍在使用中。永遠不會導致永久持有對象的內存泄漏。

在你的例子集hm = null;中看到了WeakHashMap清理的魔力。

+0

是,設置'HM = null'在'System.gc()'清除WHM之前。謝謝,我明白了。 – Nishant

3

您對指針k1,k2,k3,k4HashMapWeakHashMap設置null仍含有這些Keys引用。並且因爲HashMap包含引用,因此GC的實際實例不會被刪除。 WeakHashMap仍然打印所有這些。

嘗試運行此示例僅與HashMap - >即使您已經清除那些引用HashMap仍將保留它們。

0

HashMap控制gc(垃圾回收器)。

gc主宰WeakHashMap。

即使我們的K1,K2,K3,K4 GC設置爲空值從HashMap中不會刪除其中的GC刪除所有這些,爲我們提供了空地圖WeakHashMap中故名WeakHashMap中