Java WeakHashMap
The WeakHashMap
class in Java, part of the java.util
package, is a unique implementation of the Map
interface that uses weak references for its keys. This feature makes WeakHashMap
particularly useful for memory-sensitive applications, where keys are automatically removed from the map once they are no longer in use elsewhere in the application (i.e., when they are garbage-collected).
A WeakHashMap
is a Map implementation where the keys are stored as weak references. A weak reference allows the garbage collector to reclaim the key objects as soon as they are no longer in use, even if they are still present in the map. This behavior helps prevent memory leaks, making WeakHashMap
particularly useful in scenarios where you want to ensure that objects are automatically removed from the map when they are no longer needed.
Key features of WeakHashMap
:
WeakHashMap
are weakly referenced, meaning they can be garbage-collected when no strong references to them exist.WeakHashMap
are strongly referenced (normal references).WeakHashMap
.WeakHashMap
is not synchronized, so it is not thread-safe by default. If you need thread-safety, you can use a ConcurrentHashMap
or synchronize it manually.The WeakHashMap
class provides a few constructors for different use cases:
WeakHashMap() // Creates an empty map with the default initial capacity (16) and load factor (0.75).
WeakHashMap(int initialCapacity) // Creates a map with the specified initial capacity.
WeakHashMap(int initialCapacity, float loadFactor) // Creates a map with the specified initial capacity and load factor.
WeakHashMap(Map<? extends K, ? extends V> m) // Creates a map with the same mappings as the specified map.
Some commonly used methods of the WeakHashMap
class are similar to those in other Map
implementations:
put(K key, V value)
: Adds a key-value pair to the map. If the key already exists, it updates the value.
map.put("apple", 1);
get(Object key)
: Retrieves the value associated with the specified key.
Integer value = map.get("apple"); // Returns the value associated with 'apple'
containsKey(Object key)
: Checks if the map contains the specified key.
boolean exists = map.containsKey("apple"); // Returns true if "apple" is a key in the map
remove(Object key)
: Removes the key-value pair associated with the specified key.
map.remove("apple"); // Removes the key-value pair for 'apple'
size()
: Returns the number of key-value pairs in the map.
int size = map.size(); // Returns the number of entries in the map
keySet()
: Returns a set view of all the keys in the map.
Set<String> keys = map.keySet(); // Returns a Set of all the keys
clear()
: Removes all key-value pairs from the map.
map.clear(); // Clears the map
Here's an example that demonstrates how a WeakHashMap
works:
import java.util.WeakHashMap;
import java.util.Map;
public class WeakHashMapExample {
public static void main(String[] args) {
// Create a WeakHashMap
Map<String, Integer> map = new WeakHashMap<>();
// Add some key-value pairs to the map
map.put("apple", 1);
map.put("banana", 2);
map.put("orange", 3);
// Print the map size
System.out.println("Size before GC: " + map.size()); // Output: 3
// Make the key "banana" eligible for garbage collection
String keyToGC = "banana";
keyToGC = null;
// Suggest garbage collection
System.gc();
// Print the map size after garbage collection
System.out.println("Size after GC: " + map.size()); // Output: 2 (if "banana" is garbage collected)
}
}
Output:
Size before GC: 3
Size after GC: 2
In this example:
WeakHashMap
and add some key-value pairs."banana"
to null
, the key becomes eligible for garbage collection.System.gc()
, the garbage collector may remove the entry with the "banana"
key from the map, reducing the map size.In this example, we use custom objects as keys in a WeakHashMap
:
import java.util.WeakHashMap;
class Person {
String name;
Person(String name) {
this.name = name;
}
@Override
protected void finalize() {
System.out.println(name + " is being garbage collected");
}
}
public class WeakHashMapCustomObjectExample {
public static void main(String[] args) {
// Create a WeakHashMap with Person objects as keys
WeakHashMap<Person, String> map = new WeakHashMap<>();
// Create some Person objects and add them to the map
Person person1 = new Person("John");
Person person2 = new Person("Alice");
map.put(person1, "Engineer");
map.put(person2, "Doctor");
// Print map size
System.out.println("Map size before GC: " + map.size()); // Output: 2
// Remove strong references to person1
person1 = null;
// Suggest garbage collection
System.gc();
// Print map size after GC
System.out.println("Map size after GC: " + map.size()); // Output: 1 (if person1 is garbage collected)
}
}
Output:
Map size before GC: 2
John is being garbage collected
Map size after GC: 1
In this example:
Person
objects as keys in a WeakHashMap
.person1
is set to null
, it becomes eligible for garbage collection.System.gc()
is called, person1
is garbage collected, and the map is updated accordingly.put()
, get()
, and remove()
in WeakHashMap
are generally O(1) on average. However, the process of checking for garbage-collected keys might add a slight overhead compared to other Map
implementations.WeakHashMap
is directly tied to garbage collection. If keys are not reachable, they will be removed from the map automatically. This makes WeakHashMap
useful for managing memory but also means that the size of the map can fluctuate unpredictably as the garbage collector runs.You should use WeakHashMap
in scenarios where: