📜  Java中的WeakHashMap entrySet()方法(1)

📅  最后修改于: 2023-12-03 15:31:57.662000             🧑  作者: Mango

Java中的WeakHashMap entrySet()方法

简介

WeakHashMapJava 内置的一个以弱引用方式管理元素的 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.Entry 对象包含的 key 和 value 可能已经被回收,只是占据着一个 Entry 对象的位置。
示例
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 的生命周期,该键值对在遍历期间始终存在,直到循环结束。