Open In App

Java Program to Implement WeakHashMap API

Last Updated : 21 Jun, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

The WeakHashMap class is part of the Java Collections Framework, implementing the Map interface and extending the AbstractMap class. The Map interface helps us map key to values, while the AbstractMap class makes implementing the Map interface easier. 

Every key in a map must be unique and can unite with a maximum of one value. Do note that a map itself cannot be a key. The order of key-value pairs is not guaranteed in a WeakHashMap. What makes WeakHashMap different from a regular HashMap is that a WeakHashMap uses weak keys.

Strong Reference: A Strong reference is the type of reference that is generally used. The garbage collector does not reclaim objects having a strong reference.

Example:

Geek strongRef=new Geek();

Weak Reference: If an object does not have a strong or a soft reference, the object is said to have a weak reference.

Example:

new Geek();

An explicit weak reference can also be generated using the WeakReference class

Example:

WeakReference<Geek> weakRef=new WeakReference(new Geek());

// Now use the get() method to obtain the object
// weakRef.get()

The Presence of weak keys means the garbage collector will remove the keys once they are no longer in usage. On the other hand, the values are held by Strong references. So the value objects must not refer directly to their key else; this will prevent the key from being reclaimed. WeakHashMap supports null keys as well as values.

Load factor: The percentage of occupancy after which the capacity of WeakHashMap gets doubled. E.g. If the initial capacity is 16 and the load factor is 0.75 (75%) i.e. 12., then on the addition of the 13th element the size of WeakHashMap gets doubled.

Constructors: The WeakHashMap class provides 4 constructors:

1.WeakHashMap(): This will generate a WeakHashMap object with an initial capacity of 16 and a load factor of 0.75

Syntax:

WeakHashMap<K,V> wHM=new WeakHashMap<K,V>();

2.WeakHashMap(int InitialCapacity): This will generate a WeakHashMap object with the desired InitialCapacity and a load factor of 0.75

Syntax: 

WeakHashMap<K,V> wHM=new WeakHashMap<K,V>(20);

// This will generate a WeakHashMap 
// object with an initial capacity of 20

3.WeakHashMap(int InitialCapacity, float LoadFactor): This will generate a WeakHashMap object with the desired InitialCapacity as well as load factor.

Syntax:

WeakHashMap<K,V> wHM=new WeakHashMap<K,V>(20,0.9);

// This will generate a WeakHashMap object with an
// initial capacity of 20 and load factor of 90%

4.WeakHashMap(Map map): This will generate a WeakHashMap object and will copy all the key-value pairs from the specified map in the process.

Syntax:

WeakHashMap<K,V> wHM=new WeakHashMap<K,V>( oldMap);

// This will generate a WeakHashMap object and
//  will copy all the mappings of oldMap

Operations on WeakHashMap

The operations of WeakHashMap can be classified as either destructive or non-destructive. Destructive methods modify the map on which they operate. 

Destructive Operations

1. Addition or Updation

When a key is inserted into the WeakHashMap, the following process occurs internally:

  • A unique hash-code is generated for that particular key
  • This hash-code is used to generate an index value
  • The key-value pair gets stored at that particular index in the hash table

A) public T put(K key, T value): Inserts the given key-value pair in the WeakHashMap. If the key already exists then the value gets updated. This method returns the previous value for the key. If either the key is being inserted for the first time or the previous value is null then null is returned

B) public void putAll(Map m): Inserts all the mapping from map into the current map. If any keys are common then the value gets updated. If the map m specified is null then a NullPointerException is thrown.

2. Deletion

A) public void clear(): Removes all the mappings from the map

B) public T remove(Object key): Removes the mapping associated with the key obj from the map given that it exists. This method will return the value associated with the key being removed. Null will be returned either if no such key exists or if the value itself is null.

Non-Destructive Operations

Non-Destructive methods do not change the map on which they operate. The Non-Destructive methods are as follows:

1. containsKey: Returns true if the map contains the specified key, else returns false.

public boolean containsKey(Object Key)

2. containsValue: Returns true if the map contains a key with the specified value, else returns false.

public boolean containsValue(Object Value)

3. get: Returns the value attached with the specified key. null is returned either if the key doesn’t exist or if the value itself is null. 

public T get(Object Key)

4. size: Returns the number of key-value pairs present in the map at the instant when the method is called.

public int size() 

5. isEmpty: Returns true if no key-value pairs are present in the map at the instant when the method is called, else returns false.

public boolean isEmpty()

6. entrySet: A key-value pair is also known as a map entry. The Map.Entry interface allows us to work with map entries. entrySet method will return a set of all the present map entries.

public Set<Map.Entry<K,V>> entrySet()

7. keySet: Returns a set containing all the keys present in the map. The changes made in the map are reflected in this set. Conducting operations on the map and traversing the set at the same time may result in undefined behavior.

public Set<k> keySet()

8. values: Returns a Collection view of all the values present in the map. The changes made in the map are reflected in this collection. Conducting operations on the map and traversing the collection at the same time may result in undefined behavior.

public Collection<V> values()

Implementing WeakHashMap

The following program contains the WHI class, which implements the WeakHashMap API. This implementation is then used here to map grades to scores.

Java




// Java Program to implement WeakHashMap
 
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
 
// The class WHI will implement WeakHashMap
class WHI<K, V> {
 
    // Make a private WeakHashMap reference
    // variable
 
    private WeakHashMap<K, V> obj;
 
    // Constructors
 
    // Create WeakHashMap with capacity 16
    // and 0.75 load-factor
    public WHI() { obj = new WeakHashMap<K, V>(); }
 
    // Create WeakHashMap with desired capacity
    // and 0.75 load-factor
    public WHI(int initialCapacity)
    {
        obj = new WeakHashMap<K, V>(initialCapacity);
    }
 
    // Create WeakHashMap with desired capacity
    // and desired load-factor
    public WHI(int initialCapacity, float loadFactor)
    {
        obj = new WeakHashMap<K, V>(initialCapacity,
                                    loadFactor);
    }
 
    // Destructive-Methods
 
    // Place the key-value pair in the
    // WeakHashMap
 
    public V put(K key, V value)
    {
        return obj.put(key, value);
    }
 
    // Copy all the key-value pairs
    // from a map
    public void putAll(Map<K, V> map) { obj.putAll(map); }
 
    // Remove all the key-value pairs
    public void clear() { obj.clear(); }
 
    // Remove a particular key
    public V remove(Object key) { return obj.remove(key); }
 
    // Non-Destructive methods
 
    // Check if the map contains
    // a specific key
    public boolean containsKey(Object key)
    {
        return obj.containsKey(key);
    }
 
    // Check if the map contains a key
    // with specific value
    public boolean containsValue(Object value)
    {
        return obj.containsValue(value);
    }
 
    // get the value for a specific
    // key
    public V get(Object key) { return obj.get(key); }
 
    // get size of the map
    public int size() { return obj.size(); }
 
    // Check if the map is empty
    public boolean isEmpty() { return obj.isEmpty(); }
 
    // get a set of Map entries
    public Set<Map.Entry<K, V> > entrySet()
    {
        return obj.entrySet();
    }
 
    // get a set of keys
    public Set<K> keySet() { return obj.keySet(); }
 
    // get a Collection of values
    public Collection<V> values() { return obj.values(); }
}
 
public class Main {
 
    public static void main(String args[])
    {
 
        // Create an object of WHI class
        // key will be of type String
        // value will be of type Integer
        WHI<String, Integer> obj1
            = new WHI<String, Integer>();
 
        System.out.println(
            "The grades and cut off are as follows: ");
 
        // insert key-value pairs in the WeakHashMap object
 
        obj1.put("A+", 90);
        obj1.put("A", 80);
        obj1.put("B", 70);
        obj1.put("C", 60);
 
        // Traverse the set containing map entries
        // entrySet() is used to obtain the set
        for (Map.Entry<String, Integer> ivar :
             obj1.entrySet()) {
            System.out.println(ivar.getKey() + " "
                               + ivar.getValue());
        }
 
        // get value associated with key "B"
        System.out.println("The cut-off for B grade is "
                           + obj1.get("B"));
    }
}


Output

The grades and cut off are as follows: 
A+ 90
C 60
B 70
A 80
The cut-off for B grade is 70

Note: The grades and cut off might get printed in an unorderly manner. This is because the order is not guaranteed in a WeakHashMap.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads