Java WeakHashMap详解指南

培训教学 潘老师 7个月前 (10-12) 151 ℃ (0) 扫码查看

在本教程中,我们将学习Java WeakHashMap和弱引用,并提供示例。此外,我们将学习WeakHashMap与HashMap之间的区别。

1.Java WeakHashMap简介

WeakHashMap类(位于java.util包中)是Map接口的基于HashTable的实现,在Java 1.2版本以来一直存在。它几乎具有与HashMap相同的功能,包括构造函数、方法、性能和内部实现。

HashMap和WeakHashMap之间的主要区别在于后者具有弱引用键。在WeakHashMap中,当键不具有任何强引用或软引用时,垃圾收集器会自动删除条目。WeakHashMap中的每个键对象都间接存储为弱引用的引用目标。

请注意,WeakHashMap中的值对象由普通强引用持有。因此,值对象不得直接或间接强引用自己的键,这也是为了将防止键被丢弃。

在Java集合中,WeakHashMap类的声明如下:

public class WeakHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>

如上所示,它实现了Map接口并扩展了AbstractMap类。

2. 使用WeakHashMap

2.1 创建WeakHashMap

我们可以使用以下构造函数来创建WeakHashMap:

  • WeakHashMap():用于创建具有默认初始容量16和默认负载因子0.75的空Map。
  • WeakHashMap(int initialCapacity):用于创建具有给定初始容量和默认负载因子0.75的空Map。
  • WeakHashMap(int initialCapacity, float loadFactor):用于创建具有给定初始容量和给定负载因子的空Map。
  • WeakHashMap(Map m):用于创建具有与指定Map相同条目的新WeakHashMap。
WeakHashMap<String, String> map = new WeakHashMap<>();
WeakHashMap<String, String> map = new WeakHashMap<>(16);
WeakHashMap<String, String> map  = new WeakHashMap<>(16, 8);
Map<String, String> map = new HashMap<String, String>() {{
    put("key1", "value1");
    put("key2", "value2");
}};
WeakHashMap<String, String> map = new WeakHashMap<>(map);

2.2 WeakHashMap方法

  • WeakHashMap类中的一些重要方法包括:
  • Object put(key, value):将键值对插入Map中。
  • Object get(key):返回Map中指定键的值。
  • boolean containsKey(key):根据指定的键是否在Map中找到返回true或false。
  • boolean containsValue(value):类似于containsKey()方法,它查找指定值而不是键。
  • Set keySet():返回Map中所有键的集合。
  • Set entrySet():返回Map中所有映射的集合。
  • Value remove(Object key):删除指定键的键值对。
  • int size():返回Map的大小,等于Map中存储的键值对数。

2.3 WeakHashMap示例

让我们快速介绍如何创建WeakHashMap以及如何使用上述描述的方法。

//创建WeakHashMap
WeakHashMap<Integer, String> map = new WeakHashMap<>();
//添加元素
map.put(1, "A");
map.put(2, "B");
map.put(3, "C");
System.out.println(map);
//取值
String value = map.get(2);
System.out.println(value);
//判断key是否存在
System.out.println(map.containsKey(3));
System.out.println(map.containsValue("Z"));
//根据key移除键值对
map.remove(3);
System.out.println(map);
//map长度
System.out.println(map.size());
//遍历
for(Map.Entry<Integer, String> entry : map.entrySet())
{
    System.out.println(entry.getKey() + " :: " + entry.getValue());
}

3. HashMap和WeakHashMap之间的区别

在Java中,对象引用可以具有多种类型。在深入探讨WeakHashMap中的弱键概念之前,让我们先讨论它们。

3.1. 强引用、软引用和弱引用

强引用是我们在正常程序中创建的引用。这些是简单的变量分配。在给定示例中,变量game对String对象(值为“cricket”)具有强引用。

//强引用
String game = "cricket";

任何具有活动强引用的对象都不符合垃圾回收的条件。软引用是显式声明的。具有软引用的对象在JVM即将因OutOfMemoryError而崩溃之前不会被垃圾回收。在回收弱引用对象所持有的内存之前,JVM会进行必要的努力。

在我们将强引用设为null之后,game对象符合垃圾回收的条件,但只有在JVM绝对需要内存时才会被回收。

// game 是强引用
String game = "cricket";
// 将强引用封装为软引用
SoftReference<String> softGame = new SoftReference<>(game);
game = null;  //现在它有资格获得GC

弱引用也是显式创建的引用,它在垃圾回收周期发生时会迅速被回收。在以下示例中,当我们将强引用设为null时,game对象可以在下一个垃圾回收周期中被回收,因为没有其他强引用指向它。

// 强引用
String game = "cricket";
// 将强引用封装为弱引用
WeakReference<String> softGame = new WeakReference<>(game);
// 将强引用设为null
game = null;  //GC可以随时回收

3.2. WeakHashMap中的垃圾回收行为

如前所述,WeakHashMap将键存储为弱引用。因此,在调用垃圾回收时,其键将符合垃圾回收的条件。

在下面的示例中,我们在Map中存储了两个条目。我们将一个键设为null。在垃圾回收运行后,Map中应该只剩下一个条目。

Map<MapKey, String> map = new WeakHashMap<>();
MapKey key1 = new MapKey("1");
MapKey key2 = new MapKey("2");
map.put(key1, "1");
map.put(key2, "2");
System.out.println(map);
key1 = null;   //使其符合GC回收条件
System.gc();
Thread.sleep(10000);
System.out.println(map);

输出:

{MapKey{key='2'}=2, MapKey{key='1'}=1}
{MapKey{key='2'}=2}

可以在WeakHashMap中放置null键或null值。垃圾回收器仅从Map中删除键(即对象)引用为null的条目。另一方面,垃圾回收器不会从WeakHashMap中删除具有null值的键。

4.WeakHashMap用途

我们可以在创建简单的缓存或注册表数据结构中使用WeakHashMap,其中我们想将对象以键值对的形式放入。当从这样的缓存中删除条目时,它将不再在应用程序中需要。

这会定期从内存中删除未使用的对象,从而使内存不会填满我们在应用程序中不再使用的匿名对象。

5.将HashMap转换为WeakHashMap

要从HashMap创建WeakHashMap,可以使用其构造函数new WeakHashMap(hashmap)。

// 创建 HashMap
HashMap<Integer, String> hashMap = new HashMap<>();
hashMap.put(1, "A");
hashMap.put(2, "B");
System.out.println("HashMap : " + hashMap);
//用HashMap创建WeakHashMap
WeakHashMap<Integer, String> weakHashMap = new WeakHashMap<>(hashMap);
System.out.println("WeakHashMap : " + weakHashMap);

输出:

HashMap : {1=A, 2=B}
WeakHashMap : {2=B, 1=A}

6.结论

这就是关于Java中的WeakHashMap的全部内容。我们已经了解了它是什么,以及它与HashMap有何不同。

我们还涵盖了涉及HashMap和WeakHashMap的实际示例以及它们在垃圾回收方面的不同行为。然后我们看到了各种引用类型,以及最后的实际用例。


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/teach/9483.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】