不可变集合
JDK9新特性
- 不可变集合:不能别修改的集合
- 长度不可修改
- 内容不可修改
不可变集合的应用场景
- 如果某个数据不能被修改,把它防御性地拷贝到不可变集合中是一个很好地时间
- 当集合对象被不可信地库调用时,不可变形式是安全地
- 简单理解:不想让别人修改集合中的内容
不可变集合的书写格式
再List、Set、Map接口中,都存在静态的of方法,可以获取一个不可变的集合
| 方法名称 | 说明 |
|---|---|
| static List of(E...elements) | 创建一个具有指定元素的List集合对象 |
| static Set of(E...element) | 创建一个具有指定元素的Set集合对象 |
| static<K, V> Map<K, V> of(E...elements) | 创建一个具有指定元素的Map集合对象 |
| static<K, V> Map<K, V> ofEntris(Entry<? entends K, ? extends V>... entries) | 创建一个具有指定元素的Map集合对象 |
| static<K, V> Map<K, V> copyOf(Map<? extends K, ? extends V> map) | JDK10: 根据传入的map集合创建不可变集合 |
**注意:**这个集合不能添加,不能删除,不能修改
细节
-
当我们要获取一个不可变的Set集合时,里面的参数一定要保证唯一性
-
当我们要获取一个不可变的Map集合时,键不能重复
-
Map里面的of方法,参数是有上限的,最多只能有20个参数,即10个键值对,因为形参里面不能有多个可变参数
-
如果我们传递多个键值对对象,数量大于10个,可以使用Map中的ofEntries方法
- 方法原理:这个方法里面的形参是可变参数,而可变参数在底层就是一个数组,因此我们只需要获取entry数组再传入就行
//获取所有的键值对对象(Entry对象)
Set<Map.Enter<String, String>> entries = hm.entrySet();
//调用toArray方法将Set集合变成数组
Map.Entry[] arr1 = entries.toArray(new Map.Entry[0]);
//toArray方法再底层会比较集合的长度跟数组的长度两者的大小
//如果集合的长度 > 数组的长度:数据再数组中放不下,此时会根据实际数据的个数,重新创建数组
//如果集合的长度 <= 数组的长度:数据再数组中放得下,此时不会创建新的数组,而是直接用
//调用ofEntries方法创建不可变集合
Map<String, String> map = Map.ofEntries(arr1);
- 链式法则简化
Map<String, String> map = Map.ofEntries(hm.entrySet().toArray(new Map.Entry[0]))
- copyOf方法底层原理
- 首先判断传入的map集合本身是否为不可变集合
- 如果是,强制类型转换后直接返回
- 如果不是,调用ofEntries方法后强制类型转换并返回
- 首先判断传入的map集合本身是否为不可变集合
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]));
}
}