Java WeakHashMap 类
- WeakHashMap 的基本特性:
WeakHashMap
是 Java 集合框架的一部分,实现了 Map 接口,主要特点是它的键是弱引用类型,可以在不再使用时被垃圾回收。 - 创建和使用:创建
WeakHashMap
时可以指定容量和负载因子。它提供了标准的映射操作方法,如put()
、get()
和remove()
,且可以从其他映射类型创建。 - 与 HashMap 的区别:
WeakHashMap
与HashMap
的主要区别在于键的弱引用性质。在WeakHashMap
中,一旦键不再被使用,相关的键值对可能会被垃圾回收器移除,而在HashMap
中,条目总是保持不变直到显式移除。
Java 集合框架中的 WeakHashMap
类提供了哈希表数据结构的特性。
它实现了 Map 接口。
注意:weak hashmap 的键是 WeakReference 类型。
如果程序中不再使用引用,则 Java 中的弱引用类型对象可以被垃圾回收。
让我们首先学习创建 weak hash map。然后,我们将学习它与 hashmap 的不同之处。
创建 WeakHashMap
要创建 weak hashmap,我们首先需要导入 java.util.WeakHashMap
包。一旦我们导入了包,下面是我们在 Java 中创建 weak hashmaps 的方法。
// 创建容量为 8,负载因子为 0.6 的 WeakHashMap
WeakHashMap<Key, Value> numbers = new WeakHashMap<>(8, 0.6);
在上面的代码中,我们创建了一个名为 numbers
的 weak hashmap。
这里,
Key
- 用于在映射中将每个元素(值)关联的唯一标识符Value
- 由键在映射中关联的元素
注意 new WeakHashMap<>(8, 0.6)
这部分。这里,第一个参数是 容量,第二个参数是 负载因子。
- 容量 - 这个映射的容量是 8。意味着它可以存储 8 个条目。
- 负载因子 - 这个映射的负载因子是 0.6。这意味着当我们的哈希表填充到 60% 时,条目会被移到一个新的哈希表中,其大小是原始哈希表的两倍。
默认容量和负载因子
可以创建一个未定义容量和负载因子的 weak hashmap。例如,
// 使用默认容量和负载因子的 WeakHashMap
WeakHashMap<Key, Value> numbers1 = new WeakHashMap<>();
默认情况下,
- 映射的容量将是 16
- 负载因子将是 0.75
HashMap 和 WeakHashMap 的区别
让我们看看 Java 中 weak hashmap 的实现。
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
// 创建 WeakHashMap of numbers
WeakHashMap<String, Integer> numbers = new WeakHashMap<>();
String two = new String("Two");
Integer twoValue = 2;
String four = new String("Four");
Integer fourValue = 4;
// 插入元素
numbers.put(two, twoValue);
numbers.put(four, fourValue);
System.out.println("WeakHashMap: " + numbers);
// 将引用置为 null
two = null;
// 执行垃圾回收
System.gc();
System.out.println("WeakHashMap 在垃圾回收后: " + numbers);
}
}
输出
WeakHashMap: {Four=4, Two=2}
WeakHashMap 在垃圾回收后: {Four}
如我们所见,当 weak hashmap 的键 two
被设置为 null
并执行垃圾回收时,该键被移除。
这是因为与 hashmap 不同,weak hashmap 的键是 弱引用 类型。这意味着如果不再使用映射条目的键,则该条目会被垃圾回收器移除。这对节省资源很有用。
现在让我们看看在 hashmap 中的相同实现。
import java.util.HashMap;
class Main {
public static void main(String[] args) {
// 创建包含偶数的 HashMap
HashMap<String, Integer> numbers = new HashMap<>();
String two = new String("Two");
Integer twoValue = 2;
String four = new String("Four");
Integer fourValue = 4;
// 插入元素
numbers.put(two, twoValue);
numbers.put(four, fourValue);
System.out.println("HashMap: " + numbers);
// 将引用置为 null
two = null;
// 执行垃圾回收
System.gc();
System.out.println("垃圾回收后的 HashMap: " + numbers);
}
}
输出
HashMap: {Four=4, Two=2}
垃圾回收后的 HashMap: {Four=4, Two=2}
这里,当 hashmap 的键 two
被设置为 null
并执行垃圾回收时,该键并未被移除。
这是因为与 weak hashmaps 不同,hashmaps 的键是 强引用 类型。这意味着即使不再使用映射条目的键,垃圾回收器也不会移除该条目。
注意:hashmaps 和 weak hashmaps 的所有功能都相似,除了 weak hashmap 的键是弱引用,而 hashmap 的键是强引用。
从其他映射创建 WeakHashMap
以下是我们如何从其他映射创建 weak hashmap。
import java.util.HashMap;
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
// 创建包含偶数的 hashmap
HashMap<String, Integer> evenNumbers = new HashMap<>();
String two = new String("Two");
Integer twoValue = 2;
evenNumbers.put(two, twoValue);
System.out.println("HashMap: " + evenNumbers);
// 从其他 hashmap 创建 weak hash map
WeakHashMap<String, Integer> numbers = new WeakHashMap<>(evenNumbers);
System.out.println("WeakHashMap: " + numbers);
}
}
输出
HashMap: {Two=2}
WeakHashMap: {Two=2}
WeakHashMap 的方法
WeakHashMap
类提供了多种方法,允许我们在映射上执行各种操作。
向 WeakHashMap 插入元素
put()
- 将指定的键/值映射插入到映射中putAll()
- 将指定映射的所有条目插入到此映射中putIfAbsent()
- 如果指定键在映射中不存在,则将指定的键/值映射插入到映射中
例如,
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
// 创建包含偶数的 WeakHashMap
WeakHashMap<String, Integer> evenNumbers = new WeakHashMap<>();
String two = new String("Two");
Integer twoValue = 2;
// 使用 put()
evenNumbers.put(two, twoValue);
String four = new String("Four");
Integer fourValue = 4;
// 使用 putIfAbsent()
evenNumbers.putIfAbsent(four, fourValue);
System.out.println("包含偶数的 WeakHashMap: " + evenNumbers);
// 创建包含数字的 WeakHashMap
WeakHashMap<String, Integer> numbers = new WeakHashMap<>();
String one = new String("One");
Integer oneValue = 1;
numbers.put(one, oneValue);
// 使用 putAll()
numbers.putAll(evenNumbers);
System.out.println("包含数字的 WeakHashMap: " + numbers);
}
}
```**输出**
```java
包含偶数的 WeakHashMap: {Four=4, Two=2}
包含数字的 WeakHashMap: {Two=2, Four=4, One=1}
访问 WeakHashMap 元素
1. 使用 entrySet()、keySet() 和 values()
entrySet()
- 返回映射中所有键/值映射的集合keySet()
- 返回映射中所有键的集合values()
- 返回映射中所有值的集合
例如,
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
// 创建包含偶数的 WeakHashMap
WeakHashMap<String, Integer> numbers = new WeakHashMap<>();
String one = new String("One");
Integer oneValue = 1;
numbers.put(one, oneValue);
String two = new String("Two");
Integer twoValue = 2;
numbers.put(two, twoValue);
System.out.println("WeakHashMap: " + numbers);
// 使用 entrySet()
System.out.println("键/值映射: " + numbers.entrySet());
// 使用 keySet()
System.out.println("键: " + numbers.keySet());
// 使用 values()
System.out.println("值: " + numbers.values());
}
}
输出
WeakHashMap: {Two=2, One=1}
键/值映射: [Two=2, One=1]
键: [Two, One]
值: [1, 2]
2. 使用 get() 和 getOrDefault()
get()
- 返回与指定键关联的值。如果找不到键,则返回null
。getOrDefault()
- 返回与指定键关联的值。如果找不到键,则返回指定的默认值。
例如,
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
// 创建包含偶数的 WeakHashMap
WeakHashMap<String, Integer> numbers = new WeakHashMap<>();
String one = new String("One");
Integer oneValue = 1;
numbers.put(one, oneValue);
String two = new String("Two");
Integer twoValue = 2;
numbers.put(two, twoValue);
System.out.println("WeakHashMap: " + numbers);
// 使用 get()
int value1 = numbers.get("Two");
System.out.println("使用 get(): " + value1);
// 使用 getOrDefault()
int value2 = numbers.getOrDefault("Four", 4);
System.out.println("使用 getOrDefault(): " + value2);
}
}
输出
WeakHashMap: {Two=2, One=1}
使用 get(): 2
使用 getOrDefault(): 4
移除 WeakHashMap 元素
remove(key)
- 返回并移除映射中与指定键关联的条目remove(key, value)
- 只有当指定键映射到指定值时,才从映射中移除条目,并返回一个布尔值
例如,
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
// 创建包含偶数的 WeakHashMap
WeakHashMap<String, Integer> numbers = new WeakHashMap<>();
String one = new String("One");
Integer oneValue = 1;
numbers.put(one, oneValue);
String two = new String("Two");
Integer twoValue = 2;
numbers.put(two, twoValue);
System.out.println("WeakHashMap: " + numbers);
// 使用单参数的 remove()
int value = numbers.remove("Two");
System.out.println("移除的值: " + value);
// 使用两个参数的 remove()
boolean result = numbers.remove("One", 3);
System.out.println("条目 {One=3} 是否被移除? " + result);
System.out.println("更新后的 WeakHashMap: " + numbers);
}
}
输出
WeakHashMap: {Two=2, One=1}
移除的值: 2
条目 {One=3} 是否被移除? false
更新后的 WeakHashMap: {One=1}
WeakHashMap 的其他方法
方法 | 描述 |
---|---|
clear() | 从映射中移除所有条目 |
containsKey() | 检查映射是否包含指定的键,并返回布尔值 |
containsValue() | 检查映射是否包含指定的值,并返回布尔值 |
size() | 返回映射的大小 |
isEmpty() | 检查映射是否为空,并返回布尔值 |
要了解更多,请访问 Java WeakHashMap (官方 Java 文档)。