Java WeakHashMap
WeakHashMap 的键是弱引用,很适合内存敏感的场景,比如缓存。在本教程中,我们将通过示例学习 Java WeakHashMap 类及其操作。我们还将了解 WeakHashMap 和 HashMap 之间的区别。
在本教程中,我们将通过示例学习 Java WeakHashMap 类及其操作。我们还将了解 WeakHashMap 和 HashMap 之间的区别。
WeakHashMap
的键是弱引用类型(WeakReference
)的,很适合内存敏感的场景,比如缓存。
如果弱引用类型的对象在程序中不再使用或者指向 null
,Java 中进行垃圾回收的时候,可以立刻进行回收。本教程的后面我们会通过实例展示。
WeakHashMap
与 HashMap
一样,实现了Map 接口。
让我们先学习如何创建 WeakHashMap。然后再了解它与 HashMap 的不同之处。
创建 WeakHashMap
我们先导入 java.util.WeakHashMap
类就可以使用构造方法创建 WeakHashMap 对象了。
// 使用初始容量和负载因子构造 WeakHashMap 对象
WeakHashMap<Key, Value> numbers = new WeakHashMap<>(8, 0.6);
在上面的代码中,我们创建了一个名为 numbers
的 WeakHashMap 对象。
这里,
Key
- Map 中键的数据类型Value
- Map 中值的数据类型
注意表达式 new WeakHashMap<>(8, 0.6)
。这里,第一个参数是容量,第二个参数是负载因子。
- capacity - 此 Map 的容量为 8。意思是,最开始它可以存储 8 个条目。
- loadFactor - 此 Map 的负载因子为 0.6。这意味着每当我们的 Map 被装满 60% 时,就要扩容。
默认容量和负载系数
可以在不定义其容量和负载因子的情况下创建 WeakHashMap 。例如,
WeakHashMap<Key, Value> numbers1 = new WeakHashMap<>();
默认情况下:
- 初始容量将为
16
- 负载系数将为
0.75
HashMap 和 WeakHashMap 的区别
让我们先看看 WeakHashMap 的实例。
import java.util.WeakHashMap;
public class Main {
public static void main(String[] args) {
// Creating 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;
// Inserting elements
numbers.put(two, twoValue);
numbers.put(four, fourValue);
System.out.println("WeakHashMap: " + numbers);
// Make the reference null
two = null;
// Perform garbage collection
System.gc();
System.out.println("WeakHashMap after garbage collection: " + numbers);
}
}
输出
WeakHashMap: {Four=4, Two=2}
WeakHashMap after garbage collection: {Four=4}
正如我们所见,当 WeakHashMap 中的键 two
被设置为 null
, 并执行垃圾收集后,键被删除。
与 HashMap 不同,WeakHashMap 的键是弱引用类型。这意味着如果不再使用该条目的键,则垃圾收集器将删除该条目。这对于节省资源很有用。
现在让我们使用 HashMap 实现的相同的示例。
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
// Creating HashMap of even numbers
HashMap<String, Integer> numbers = new HashMap<>();
String two = new String("Two");
Integer twoValue = 2;
String four = new String("Four");
Integer fourValue = 4;
// Inserting elements
numbers.put(two, twoValue);
numbers.put(four, fourValue);
System.out.println("HashMap: " + numbers);
// Make the reference null
two = null;
// Perform garbage collection
System.gc();
System.out.println("HashMap after garbage collection: " + numbers);
}
}
输出
HashMap: {Four=4, Two=2}
HashMap after garbage collection: {Four=4, Two=2}
在这里,当 HashMap 中的键 two
被设置为 null
, 并执行垃圾收集后,键不会被删除。
这是因为 HashMap 的键是强引用类型。这意味着即使不再使用该条目的键,垃圾收集器也不会删除键所在的条目。
注意: HashMap
和 WeakHashMap
的所有功能都相似,只是 WeakHashMap
的键是弱引用,而 hashmap 的键是强引用。
从其他 Map 创建 WeakHashMap
以下是我们如何从其他 Map 创建 WeakHashMap。
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
public class Main {
public static void main(String[] args) {
// 创建一个 HashMap 对象
Map<String, Integer> evenNumbers = new HashMap<>();
String two = new String("Two");
Integer twoValue = 2;
evenNumbers.put(two, twoValue);
System.out.println("HashMap: " + evenNumbers);
// 将 HashMap 转换为 WeakHashMap
WeakHashMap<String, Integer> numbers = new WeakHashMap<>(evenNumbers);
System.out.println("WeakHashMap: " + numbers);
}
}
输出
HashMap: {Two=2}
WeakHashMap: {Two=2}
WeakHashMap 的方法
WeakHashMap
类实现了 Map
接口定义的所有操作。
向 WeakHashMap 插入元素
put()
- 将指定的键值对条目插入到 Map 中putAll()
- 将指定 Map 中的所有条目插入到此 Map 中putIfAbsent()
- 如果 Map 中不存在指定的键,则将指定的键值对条目插入到 Map 中
例如,
import java.util.WeakHashMap;
public class Main {
public static void main(String[] args) {
// Creating WeakHashMap of even numbers
WeakHashMap<String, Integer> evenNumbers = new WeakHashMap<>();
String two = new String("Two");
Integer twoValue = 2;
evenNumbers.put(two, twoValue);
String four = new String("Four");
Integer fourValue = 4;
evenNumbers.putIfAbsent(four, fourValue);
System.out.println("WeakHashMap of even numbers: " + evenNumbers);
WeakHashMap<String, Integer> numbers = new WeakHashMap<>();
String one = new String("One");
Integer oneValue = 1;
numbers.put(one, oneValue);
numbers.putAll(evenNumbers);
System.out.println("WeakHashMap of numbers: " + numbers);
}
}
输出
WeakHashMap of even numbers: {Four=4, Two=2}
WeakHashMap of numbers: {Two=2, Four=4, One=1}
entrySet()、keySet() 和 values()
entrySet()
- 返回 Map 的所有键值对条目的 Set 集合keySet()
- 返回 Map 的所有键组成的 Set 集合values()
- 返回 Map 的所有值组成的集合
例如,
import java.util.WeakHashMap;
public class Main {
public static void main(String[] args) {
// Creating WeakHashMap of even numbers
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);
System.out.println("Key/Value mappings: " + numbers.entrySet());
System.out.println("Keys: " + numbers.keySet());
System.out.println("Values: " + numbers.values());
}
}
输出
Key/Value mappings: [Two=2, One=1]
Keys: [Two, One]
Values: [2, 1]
get() 和 getOrDefault()
get()
- 返回与指定键关联的值。 如果未找到键,则返回null
。getOrDefault()
- 返回与指定键关联的值。如果未找到键,则返回指定的默认值。
例如,
import java.util.WeakHashMap;
public class Main {
public static void main(String[] args) {
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);
int value1 = numbers.get("Two");
System.out.println("Using get(): " + value1);
int value2 = numbers.getOrDefault("Four", 4);
System.out.println("Using getOrDefault(): " + value2);
}
}
输出
WeakHashMap: {Two=2, One=1}
Using get(): 2
Using getOrDefault(): 4
移除 WeakHashMap 元素
remove(key)
- 删除并返回与指定键关联的条目remove(key, value)
- 删除与指定键和指定值匹配的条目,成功返回true
,否则返回false
。
例如,
import java.util.WeakHashMap;
public class Main {
public static void main(String[] args) {
// Creating WeakHashMap of even numbers
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);
int value = numbers.remove("Two");
System.out.println("Removed value: " + value);
boolean result = numbers.remove("One", 3);
System.out.println("Is the entry {One=3} removed? " + result);
System.out.println("Updated WeakHashMap: " + numbers);
}
}
输出
WeakHashMap: {Two=2, One=1}
Removed value: 2
Is the entry {One=3} removed? false
Updated WeakHashMap: {One=1}
WeakHashMap 的其他方法
clear()
: 从 Map 中删除所有条目containsKey()
: 检查 Map 是否包含指定的键containsValue()
: 检查 Map 是否包含指定的值size()
: 返回 Map 的大小isEmpty()
: 检查 Map 是否为空