【Java集合框架】3 - 15 不可变集合
§3-15 不可变集合
3-15.1 创建方法
不可变集合,即一旦创建完成后,其长度、内容不可修改的集合。不可变集合具有以下应用场景:
- 若集合中的某个数据不能被修改,将它防御性地复制到不可变集合中较为安全;
- 当集合对象被不可信的库调用时,不可变形式是安全的。
简而言之,不可变集合不希望,也不允许他人修改其中的内容。在这种情况下,不可变集合只允许查询操作。
在 List
, Set
和 Map
接口中,都有静态的 of
方法,可以获取一个不可变集合。
静态方法:
静态方法 | 描述 |
---|---|
List<E> of(E... elements) |
创建一个具有指定元素的 List 对象 |
Set<E> of(E... elements) |
创建一个具有指定元素的 Set 对象 |
Map<K,V> of(K k1, V v1, ...) |
创建一个具有指定数量映射的 Map 对象 |
Map<K,V> ofEntries(Map.Entry<? extends K, ? extends V>... entries) |
创建一个具有指定条目的 Map 对象 |
注意:
-
of
方法返回的都是不可变的集合对象,若传入参数为空,则返回一个不可变空集合; -
强行尝试增加、删除、修改操作会抛出异常
UnsupportedOperationException
; -
Set
和Map
要求键不可重复,若传入重复元素,则会抛出异常IllegalArgumentException
; -
传出的不可变
List
的运行时类为java.util.ImmutableCollections$ListN
,该类继承自java.util.ImmutableCollections$AbstractImmutableList
,后者实现了List<E>
接口; -
传出的不可变
Set
的运行时类为java.util.ImmutableCollections$SetN
,该类继承自java.util.ImmutableCollections$AbstractImmutableSet
,后者实现了Set<E>
接口; -
传出的不可变
Map
的运行时类为java.util.ImmutableCollections$MapN
,该类继承自java.util.ImmutableCollections&AbstractImmutableMap
,后者继承了AbstractMap
,进而实现Map<K,V>
接口; -
可变参数实际上是一个数组,因此可以往可变参数传入数组;
-
获取不可变
Map
,除了可以结合连点式使用ofEntries
获取之外,也可以调用Map.copyOf
方法://ofEntries:会自动根据长度创建新数组 Map<String, String> map = Map.ofEntries(hm.entrySet().toArray(new Map.Entry[0])); //自 JDK 10 Map<String, String> map = Map.copyOf(hm);
该方法的实现为:
static <K, V> Map<K, V> copyOf(Map<? extends K, ? extends V> map) { if (map instanceof ImmutableCollections.AbstractImmutableMap) { return (Map<K,V>)map; } else { return (Map<K,V>)Map.ofEntries(map.entrySet().toArray(new Entry[0])); } }