Question

I create a WeakHashMap as

WeakHashMap<Employee,String> map = new WeakHashMap<Employee,String>();
map.put(emp,"hello");

where emp is an Employee object. Now if I do emp = null or say emp object is no longer referenced, then will the entry be removed from the WeakHashMap i.e. will the size of Map be zero?
And will it be vice-versa in case of HashMap?
Is my understanding of WeakHashMap correct?

Was it helpful?

Solution 2

I ran the sample code to understand the difference between HashMap and WeakHashMap

            Map hashMap= new HashMap();
            Map weakHashMap = new WeakHashMap();

            String keyHashMap = new String("keyHashMap");
            String keyWeakHashMap = new String("keyWeakHashMap");

            hashMap.put(keyHashMap, "helloHash");
            weakHashMap.put(keyWeakHashMap, "helloWeakHash");
            System.out.println("Before: hash map value:"+hashMap.get("keyHashMap")+" and weak hash map value:"+weakHashMap.get("keyWeakHashMap"));

            keyHashMap = null;
            keyWeakHashMap = null;

            System.gc();  

            System.out.println("After: hash map value:"+hashMap.get("keyHashMap")+" and weak hash map value:"+weakHashMap.get("keyWeakHashMap"));

The output will be:

Before: hash map value:helloHash and weak hash map value:helloWeakHash
After: hash map value:helloHash and weak hash map value:null

OTHER TIPS

A very simple example, to enlighten what has already been said :

import java.util.WeakHashMap;

public class WeakHashMapDemo {

    public static void main(String[] args) {
        // -- Fill a weak hash map with one entry
        WeakHashMap<Data, String> map = new WeakHashMap<Data, String>();
        Data someDataObject = new Data("foo");
        map.put(someDataObject, someDataObject.value);
        System.out.println("map contains someDataObject ? " + map.containsKey(someDataObject));

        // -- now make someDataObject elligible for garbage collection...
        someDataObject = null;

        for (int i = 0; i < 10000; i++) {
            if (map.size() != 0) {
                System.out.println("At iteration " + i + " the map still holds the reference on someDataObject");
            } else {
                System.out.println("somDataObject has finally been garbage collected at iteration " + i + ", hence the map is now empty");
                break;
            }
        }
    }

    static class Data {
        String value;
        Data(String value) {
            this.value = value;
        }
    }
}

Output :

    map contains someDataObject ? true
    ...
    At iteration 6216 the map still holds the reference on someDataObject
    At iteration 6217 the map still holds the reference on someDataObject
    At iteration 6218 the map still holds the reference on someDataObject
    somDataObject has finally been garbage collected at iteration 6219, hence the map is now empty

*will the entry be removed from the WeakHashMap i.e. will the size of Map be zero? *

If emp contained the last reference making the Employee strongly reachable then the entry in the map may be removed.

The Java docs sums it up pretty well:

A hashtable-based Map implementation with weak keys. An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. More precisely, the presence of a mapping for a given key will not prevent the key from being discarded by the garbage collector [...]. When a key has been discarded its entry is effectively removed from the map, so this class behaves somewhat differently from other Map implementations.

 

And will it be vice-versa in case of HashMap?

Removing the entry from the WeakHashMap will not affect any other references in the program.

WeakHashMap example:

Map map = new WeakHashMap();
Foo foo =  new Foo();
map.put(foo, "bar");
foo=null; // strong refrence is removed and object is available for garbage collection.  

HashMap example:

Map map = new HashMap();
Foo foo =  new Foo();
map.put(foo, "bar");
foo=null; // even though the reference is nullified object will not garbage collected because map is having Strong refrence.

Reference in java are memory address where the created objects points in the memory. In a WeakHashMap, concept of Weak Reference is used.

As soon as you create an object in java and assign it to some variable, it becomes strongly reachable.

Weak reference object can somewhat be similar to object that has no memory references i.e. it can be garbage collected now.

In other Map implementations like a HashMap, the keys are strongly reachable. For example, if a HashMap has keys as Person class as shown below and if Person object is set to null, even after this if we will do map.get(Person) we will get the value from the memory since the keys are strongly referenced in a HashMap.

wm.put(person, person.getFirstName());
person = null;
System.gc();
System.out.println("Hash Map :" + wm.toString());

Output : Hash Map :{test.Person@12dacd1=John}

Compared to HashMap, WeakHashMap is the one which will remove its enteries as soon as the keys have no reference in the memory. For example, if a WeakHashMap has keys as Person class as shown below and if Person object is set to null, now if you do map.get(Person) we will get null out of it because the key has no reference (or rather weakly reachable).

wm.put(person, person.getFirstName());
person = null;
System.gc();
System.out.println("Weak Hash Map :" + wm.toString());

Output : Weak Hash Map :{}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top