Java中的WeakHashMap是中高级Java开发人员中非常流行的数据结构。
WeakHashMap类位于java.util包中。 这是一个Map实现,其中存储了对其键的弱引用。 当关联密钥丢失其所有活动的强引用和软引用时, WeakHashMap中的条目将自动删除。
在本文中,我们将首先讨论Java中的引用类型-软引用,弱引用和强引用。 然后,我们将了解WeakHashMap 。
Java引用的类型:
Java允许具有三种不同类型的引用:
1.强引用:
在日常Java编程中使用的是强引用:
Employee emp = new Employee("Jake");
强引用所引用的任何对象均不符合垃圾回收的条件。
2.软参考:
在JVM绝对需要内存之前,不会对软引用指向的对象进行垃圾回收。 我们可以创建一个java.lang.ref。 SoftReference,例如 :
SoftReference<Employee> empSoft = new SoftReference<>(new Employee("Jake"));
3.参考文献少:
我们可以使用java.lang.ref.WeakReference类创建WeakReference。 任何丢失所有强引用和软引用的对象都将立即有资格进行垃圾回收 ,即使我们有一些指向它的弱引用也是如此:
Employee jake = new Employee("Jake");
Employee jakeOtherStrongRef = jake;WeakReference<Employee> emp = new WeakReference<>(jake);jake = null; // object not yet eligible for GC as jakeOtherStrongRef also exists
jakeOtherStrongRef = null; //object is now eligible for GC
Java WeakHashMap是一个哈希实现,它的键包含WeakReference 。 就像HashMap一样 ,它也支持null键和null值。 我们可以使用可用的构造函数之一创建WeakHashMap:
- WeakHashMap():创建一个空的WeakHashMap ,其默认容量为(16),默认负载因子为(0.75)
- WeakHashMap(int initialCapacity):创建具有给定容量和默认加载因子的空WeakHashMap
- WeakHashMap(int initialCapacity,float loadFactor):使用给定的初始容量和负载因子来实例化WeakHashMap
- WeakHashMap(Map <?扩展K ,?扩展V> map):构造一个新的WeakHashMap ,其映射与指定的Map相同。
让我们使用默认构造函数快速实例化WeakHashMap :
WeakHashMap<Integer, String> map = new WeakHashMap<>();
WeakHashMap实现Map接口,因此继承了其所有方法。 让我们看一下最常用的方法:
- V put(K key,V value):在WeakHashMap中插入一个新的键值对。 如果映射已经包含给定键,则其值将被替换
- V get(Object key):获取给定键的值。 如果映射不包含键的映射,则返回null
- V remove(Object key):删除具有给定键的条目并返回关联的值
- boolean containsKey(Object key):如果地图包含给定键,则返回true ,否则返回false
- boolean containsValue(Object value):检查地图是否包含给定值
- int size():获取WeakHashMap的大小
- boolean isEmpty():返回地图是否为空
- Set <Map.Entry <K,V >> entrySet():返回地图中包含的映射的Set视图
- Set <K> keySet():返回地图中包含的键的Set视图
- Collection <V> values():返回包含在映射中的值的Collection视图
让我们尝试以下几种方法:
map.put(1, "Argon");
map.put(2, "Nitrogen");System.out.println(map.containsKey(1)); //true
System.out.println(map.containsKey(3)); //false
System.out.println(map.containsValue("Nitrogen")); //trueString val = map.get(2); // "Nitrogen"
int size = map.size(); //2for(Map.Entry<Integer, String> entry : map.entrySet()) {System.out.println(entry.getKey() + ":" + entry.getValue());
}
我们之前讨论过, WeakHashMap与HashMap不同,它存储键的弱引用。
现在,让我们借助一个示例来理解这个概念。
假设我们有一个Employee类:
class Employee {private int id;private String name;//constructors, getters and setterspublic String toString() {return "[Employee{id=" + id + " ,name=" + name + "}]";}
}
并说我们定义了一个WeakHashMap <Employee,Integer> ,它存储每个Employee的依赖项数量:
Map<Employee, Integer> weakHashMap = new WeakHashMap<>();Employee ray = new Employee(1, "Ray");
Employee sierra = new Employee(2, "Sierra");weakHashMap.put(ray, 3);
weakHashMap.put(sierra, 4);System.out.println(weakHashMap); //{[Employee{id=1 ,name=Ray}]=3, [Employee{id=2 ,name=Sierra}]=4} sierra = null;System.gc();System.out.println(weakHashMap); //{[Employee{id=1 ,name=Ray}]=3}
显然,我们可以看到现在WeakHashMap不再包含sierra的条目。 换句话说,当我们将sierra指向的对象设置为null并有资格进行垃圾回收时,它失去了唯一的强引用。 在使用System.gc()请求垃圾收集时,垃圾收集器从WeakHashMap中删除了该条目。
让我们讨论一下HashMap和WeakHashMap之间的重要区别:
哈希图 | WeakHashMap |
---|---|
存储的条目对象不符合垃圾回收条件 | 当WeakHashMap中的条目丢失所有强引用和软引用时,该条目将被自动删除 |
HashMap对其关键对象拥有强大的引用 | 如果使用WeakHashMap,则会存储对键的弱引用 |
除非我们显式添加或删除条目,否则size()方法将始终返回相同的值 | size()方法可能返回较小的值,因为GC可能会自动删除一些条目 |
HashMap实现了Cloneable接口,其clone()方法返回HashMap的浅表副本 | 不实现Cloneable |
实现可序列化的接口 | 不支持序列化 |
结论:
在本教程中,我们学习了Java中的WeakHashMap 。 WeakHashMap存储对其键对象的弱引用,因此一旦键丢失所有常规引用,条目可能会自动删除。
成为第一个发表评论的人。
翻译自: https://www.javacodegeeks.com/2019/05/weakhashmap-java.html