2013-09-23 29 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中