📅  最后修改于: 2023-12-03 15:31:57.662000             🧑  作者: Mango
WeakHashMap
是 Java
内置的一个以弱引用方式管理元素的 Map
实现。它的键值对(Entry
)与普通 HashMap
相同,但键只被弱引用方式引用,当没有强引用指向它们时,这些键值对就有可能被自动从 Map 中删除。因此,WeakHashMap
常被用于缓存等内存敏感的场景。
entrySet()
是 Map
容器中常用的方法之一,用于返回该映射关系包含的所有映射关系的 Set 视图。在 WeakHashMap
中使用 entrySet()
方法需要注意其特性。
public Set<Map.Entry<K,V>> entrySet()
该方法返回映射关系的 Set 视图。
entrySet()
返回的映射关系是弱引用方式,当没有强引用指向 entrySet()
返回值的某个映射关系时,该映射关系可能被自动从 Map 中删除。WeakHashMap
可以自动删除键值对,所以 entrySet()
所返回的视图在遍历时可能动态地变化。ConcurrentModificationException
,如果在迭代期间 Map 结构发生了变化。WeakHashMap<String, String> weakHashMap = new WeakHashMap<>();
weakHashMap.put("key1", "value1");
weakHashMap.put("key2", "value2");
weakHashMap.put("key3", "value3");
weakHashMap.put("key4", "value4");
Set<Map.Entry<String, String>> entrySet = weakHashMap.entrySet();
// 遍历 entrySet
for (Map.Entry<String, String> entry : entrySet) {
System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
}
// 强引用 key3
String strongRef = "key3";
System.out.println("强引用 key3 直到循环结束前不会被回收");
for (int i = 0; i < 10; i++) {
// 遍历 entrySet
for (Map.Entry<String, String> entry : entrySet) {
System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
}
System.gc(); // 强制垃圾回收
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
运行上述示例代码,可以看到控制台输出:
key: key4, value: value4
key: key2, value: value2
key: key1, value: value1
key: key3, value: value3 // key3 尚未被回收,仍在输出中
强引用 key3 直到循环结束前不会被回收
key: key4, value: value4
key: key2, value: value2
key: key1, value: value1
key: key3, value: value3 // key3 仍在输出中
key: key4, value: value4
key: key2, value: value2
key: key1, value: value1
key: key4, value: value4 // key3 被回收了,在输出中消失了
key: key2, value: value2
key: key1, value: value1
key: key4, value: value4
key: key2, value: value2
key: key1, value: value1
key: key4, value: value4
key: key2, value: value2
key: key1, value: value1
可以看到,entrySet()
返回的视图在遍历时可能会动态地变化,因此,当 WeakHashMap
中的键值对不被强引用时,它们可能会被自动删除。在示例代码中,通过强引用方式延长了 key3
的生命周期,该键值对在遍历期间始终存在,直到循环结束。