跳到主要内容

Java WeakHashMap 类

提示
  1. WeakHashMap 的基本特性WeakHashMap 是 Java 集合框架的一部分,实现了 Map 接口,主要特点是它的键是弱引用类型,可以在不再使用时被垃圾回收。
  2. 创建和使用:创建 WeakHashMap 时可以指定容量和负载因子。它提供了标准的映射操作方法,如 put()get()remove(),且可以从其他映射类型创建。
  3. 与 HashMap 的区别WeakHashMapHashMap 的主要区别在于键的弱引用性质。在 WeakHashMap 中,一旦键不再被使用,相关的键值对可能会被垃圾回收器移除,而在 HashMap 中,条目总是保持不变直到显式移除。

Java 集合框架中的 WeakHashMap 类提供了哈希表数据结构的特性。

它实现了 Map 接口

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 文档)