In the following code example when keys are set to null and System.gc()
is called, the WeakHashMap
loses all mappings and is emptied.
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 :{}
When WeakHashMap
is used along with HashMap
and keys are set to null, the WeakHashMap
doesn't lose its key-value mappings.
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;
}
}
Output:
Weak Hash Map :{Java=Java, Hello=Hello, World=World, Programming=Programming}
Hash Map :{Programming=Programming, World=World, Java=Java, Hello=Hello}
My question is why doesn't the WeakHashMap
lose its entries in the second code example even after the keys are discarded?
A WeakHashMap
discards entries when the key is no longer strongly reachable from live code. Since the HashMap
maintains a hard reference to the keys, the keys are still reachable and the WeakHashMap
doesn't discard the entries.
The point is that the behavior has to do with references to the key objects, not to the value of any variable that might have at one time had a reference to the keys.