# 问题
35. Map.of()
方法创建的不可变集合有什么限制?
# 标准答案
Map.of()
是 Java 9 引入的一个用于创建不可变映射(Map
)的方法,它允许简洁地初始化 Map
对象。它提供了一种方式来创建小型的、不可变的映射,特别适用于常量映射的场景。然而,使用 Map.of()
方法创建的集合存在一些限制和注意事项。
# 1. 不可变性
使用 Map.of()
创建的映射是不可变的。它的核心特性是,一旦创建,这个映射就不能被修改。不能添加、删除或更改映射中的键值对。如果尝试进行这些操作,将会抛出 UnsupportedOperationException
。
例如:
Map<String, Integer> map = Map.of("a", 1, "b", 2);
map.put("c", 3); // 抛出 UnsupportedOperationException
map.remove("a"); // 抛出 UnsupportedOperationException
2
3
# 2. 键值对数量限制
Map.of()
方法可以创建一个包含最多 10 个键值对的映射。如果想要创建更多的键值对,可以使用 Map.ofEntries()
方法,它允许传递任意数量的键值对。
Map.of()
适用于最多 10 个键值对:Map.of()
:创建一个空映射。Map.of(K k1, V v1)
:创建一个包含一个键值对的映射。Map.of(K k1, V v1, K k2, V v2)
:创建一个包含两个键值对的映射,依此类推。
例如:
Map<String, Integer> map = Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i", 9, "j", 10);
超过 10 个键值对时,你需要使用 Map.ofEntries()
。
# 3. 键和值的限制
- 键和值不能为
null
:使用Map.of()
时,传入的键和值不能为空(null
)。如果传入null
值或键,会抛出NullPointerException
。
例如:
Map<String, Integer> map = Map.of("a", 1, "b", null); // 抛出 NullPointerException
Map<String, Integer> map = Map.of(null, 1); // 抛出 NullPointerException
2
# 4. 性能
虽然 Map.of()
提供了创建不可变映射的简单方法,但它的性能上并不适合动态修改的场景。由于其不可变的特性,每次尝试修改映射都会抛出异常,因此它是用于常量集合或需要频繁查找但不需要修改的场景。
# 5. 适用场景
Map.of()
适合用于需要初始化固定且小型键值对集合的场景。例如,它在处理常量映射、配置属性、返回预定义数据等方面非常有用。
# 示例
Map<String, Integer> map = Map.of("apple", 1, "banana", 2, "cherry", 3);
// 访问元素
System.out.println(map.get("apple")); // 输出 1
// 尝试修改元素
map.put("orange", 4); // 抛出 UnsupportedOperationException
2
3
4
5
6
7
在这个示例中,map
是通过 Map.of()
创建的,它是不可变的,任何修改操作都会导致异常。
# 6. Map.ofEntries()
如果需要更多的键值对,可以使用 Map.ofEntries()
,它允许传递任意数量的 Map.Entry
对象。
Map<String, Integer> map = Map.ofEntries(
Map.entry("apple", 1),
Map.entry("banana", 2),
Map.entry("cherry", 3)
);
2
3
4
5
Map.ofEntries()
提供了更灵活的方式来构建不可变映射,并支持更多的键值对。
# 总结
Map.of()
方法创建的不可变映射有以下限制:
- 不可修改:不能添加、删除或修改映射中的键值对。
- 键和值不能为
null
。 - 键值对数量有限:
Map.of()
最多支持 10 个键值对,超过此限制应使用Map.ofEntries()
。 - 适用于常量映射:适合用于需要初始化固定、不可变映射的场景。
# 核心原理
Map.of()
创建的映射是不可变的,所有的操作(如修改、删除)都被明确禁止,以确保它们是不可变的。它是利用 Java 集合的 Collections.unmodifiableMap()
来保证不可变性。
# 深入追问
🔹 Map.of()
和 Map.ofEntries()
的区别有哪些?
🔹 Map.of()
是否会影响性能?如何判断是否适合使用它?
# 相关面试题
Map.of()
方法适用于哪些场景?- 如何使用
Map.ofEntries()
初始化一个大于 10 个键值对的映射? - 为什么
Map.of()
创建的映射是不可变的?