平时创建 Map 集合,管它有几个键值对,都是使用 new 关键字,特别麻烦。在看源码的时候,发现有一个 Map.of() 方法,使用它来创建Map集合特别方便,于是拿来就用。
结果呢,第一次使用Map.of()就踩坑了,报了个空指针错误。这是为什么呢?
Map.of() 是 JDK9 引入的方法,目的是快捷创建不可变的映射。一起看下关于它的使用,顺便了解下有哪些禁忌,以防再次踩坑。
一、Map.of()简介
Map.of()是一个工厂方法,可以用于创建不可变的Map实例。
其基本形式如下:
Map<K, V> map = Map.of(K key1, V value1, K key2, V value2, ..., K keyN, V valueN);
其中,K 是键的类型,V 是值的类型。
这个方法允许创建一个包含指定键值对的不可变Map。它支持最多10个键值对的输入,超过10个键值对时就不能用了,需要使用Map.ofEntries()方法。
二、使用示例
举个简单的例子:
import java.util.Map;
public class MapOfExample{
public static void main(String[] args){
// 使用Map.of()创建一个包含几个键值对的不可变Map
Map<String, Integer> map = Map.of(
"Apple", 1,
"Banana", 2,
"Cherry", 3
);
// 打印Map
System.out.println(map);
// 访问Map中的某个值
System.out.println("Apple对应的值是:" + map.get("Apple"));
// 访问一个不存在的键
System.out.println("Grape对应的值是:" + map.get("Grape"));
}
}
示例中使用 Map.of() 方法创建了一个包含三个键值对的Map,分别是 "Apple" -> 1,"Banana" -> 2,"Cherry" -> 3。
运行结果:
{Apple=1, Banana=2, Cherry=3}
Apple对应的值是:1
Grape对应的值是:null
三、Map.of()方法的特性
不可变性
Map.of()创建的Map是不可变的。一旦我们创建了一个Map,我们不能修改它的内容(不能执行添加、删除或修改操作)。任何修改操作都会抛出UnsupportedOperationException。
例如:
Map<String, String> map = Map.of("key1", "value1", "key2", "value2");
map.put("key3", "value3"); // 抛出 UnsupportedOperationException
键值对数量限制
Map.of()最多支持10对键值对。如果我们需要创建一个包含更多键值对的映射,可以使用Map.ofEntries()方法。
Map<String, String> map = Map.of("key1", "value1", "key2", "value2", "key3", "value3", ..., "key10", "value10");
如果尝试传递超过10个键值对,则会抛出IllegalArgumentException。
空Map和单个键值对
Map.of()支持创建空Map和仅包含一个键值对的Map。
Map<String, String> emptyMap = Map.of(); // 创建一个空的不可变 Map
Map<String, String> singleEntryMap = Map.of("key1", "value1"); // 创建一个包含单个键值对的不可变 Map
空映射的返回值是Map.of()方法返回的一个空集合实例。
单个键值对的映射支持通过Map.of(K key, V value)语法进行创建。
四、Map.of()使用时的注意事项
不能包含null键或null值
Map.of()不允许传入null键或null值。如果我们尝试传入null,它将抛出NullPointerException。这是由于Map的不可变性和对键值对的严格要求,空值的支持可能导致潜在的不一致性。
Map<String, String> map = Map.of("key1", null); // 抛出 NullPointerException
Map<String, String> map2 = Map.of(null, "value1"); // 抛出 NullPointerException
不支持重复键
在Map.of()中,所有的键必须是唯一的。如果传入了重复的键,Map.of()将抛出IllegalArgumentException。因此,在调用Map.of()之前,我们需要确保每个键在Map中都是唯一的。
Map<String, String> map = Map.of("key1", "value1", "key1", "value2"); // 抛出 IllegalArgumentException
高效的内存使用
使用Map.of()创建的Map是非常轻量级和高效的,特别适用于存储少量的静态数据。它为每个键值对存储提供了紧凑的内存布局,因此相较于传统的HashMap,在性能上有优势。
只能使用不可变的数据
由于Map.of()返回的映射是不可变的,因此在使用时,键值对应该是不可变对象。如果我们将可变对象作为键或值传入并修改这些对象,将可能导致意外行为。为了避免这种情况,确保传入的键值对对象是不可变的,或只对数据进行读操作。
final Map<String, String> map = Map.of("key1", "value1");
map.put("key2", "value2"); // 抛出 UnsupportedOperationException
替代方式:Map.ofEntries()
如果我们需要创建超过10个键值对的Map,可以使用Map.ofEntries()方法。该方法接受一个Map.Entry数组,因此我们可以传入任意数量的键值对。它同样返回一个不可变的Map。
Map<String, String> largeMap = Map.ofEntries(
Map.entry("key1", "value1"),
Map.entry("key2", "value2"),
Map.entry("key3", "value3")
// 可以添加更多的键值对
);
五、Map.of()适用场景
快速创建小型的不可变Map
在需要快速构建静态映射时(比如常量、配置、静态数据等),Map.of()提供了简洁的语法,避免了写冗长的代码。
保证映射的不可变性
如果我们需要确保Map不会被修改,Map.of()是一个理想的选择。它的不可变性使得数据安全性得到了保证。
轻量级和高效的映射创建
Map.of()创建的Map在内存占用上相对较小,并且非常适合少量静态数据的存储。
最后总结
Map.of()是JDK9才有的一个非常实用的工厂方法,简化了创建不可变Map的操作,并且提高了代码的可读性。
在使用它时,我们需要注意三点:第一,只能创建不可变的Map集合;第二,键值对不能超过10对;第三,不能有空键和空值。
希望本次整理对你有帮助!