Java
介绍
- 不可变集合就是不可以被修改的集合
- 常见场景, 例如: 不想让别人修改集合中的内容, 比如斗地主的牌, 电脑硬件信息
- 特点: 只可以查询, 但不可以修改
书写格式
在List, Set, Map接口中, 都存在一个静态方法of方法, 可以获取一个不可变集合.
| 类型 | 集合 |
|---|---|
static <E> List<E> of(E... element) | List |
static <E> Set<E> of(E... element) | Set |
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) | Map |
创建不可变集合List
java
import java.util.List;
//创建不可变集合List
public class Demo1 {
public static void main(String[] args) {
List<String> list = List.of("1", "2", "3");
//对不可变集合使用除查询以外的方法, 会报错
list.add("6");
for (String s : list) {
System.out.println(s);
}
}
}危险
对不可变集合使用除查询以外的方法, 会报错java.lang.UnsupportedOperationException
创建不可变集合Set
java
import java.util.Set;
public class Demo1 {
public static void main(String[] args) {
Set<String> set = Set.of("a", "b", "c");
// 报错java.lang.UnsupportedOperationException
set.add("t");
//a b c
set.forEach(s -> System.out.println(s));
//使用注意点: 当创建一个不可变的Set集合时, 里面的参数需要保证唯一性
Set<String> set1 = Set.of("a", "a", "b", "c");
//报错java.lang.IllegalArgumentException: duplicate element: a
System.out.println(set1);
}
}危险
- 对不可变集合使用除查询以外的方法, 会报错
java.lang.UnsupportedOperationException - 当创建一个不可变的Set集合时, 里面的参数需要保证唯一性, 不然会报错
java.lang.IllegalArgumentException
创建不可变集合Map
java
import java.util.Map;
public class Demo2 {
public static void main(String[] args) {
//此方法最多只支持10对键值对
Map<String, Integer> map = Map.of("A", 1, "B", 2);
System.out.println(map);//{A=1, B=2}
// map.put("C", 3);//java.lang.UnsupportedOperationException
}
}提示
此方法最多只支持10对键值对, 如何理解呢? 如果希望一个方法可以接收多个参数, 那么第一时间想到的就是可变参数, 可使用可变参数就无法保证类型信息正确, 即无法分清是键还是值, 它们都是统一的类型.
java
public static void method(int... e) {
/* ... */
}
//无法分清是键还是值, 它们都是统一的类型
method(1, 2, 4, 3, 4, 5);ofEntries的使用
如果需要创建超过10对键值对, 可以使用Map.ofEntries()
java
import java.util.HashMap;
import java.util.Map;
public class Demo3 {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("张三", "北京");
map.put("李四", "上海");
map.put("王五", "武汉");
//1. 获取Entry对象集合
Set<Map.Entry<String, String>> entries = map.entrySet();
//使用空参默认返回Object[]类型
// Object[] arr1 = entries.toArray();
//创建长度为0的Entry数组
Map.Entry[] arr = new Map.Entry[0];
//toArray方法在底层会比较集合的长度和数组的长度两者的大小
//1. 如果集合长度 > 数组长度 ==> 数据在数据中放不下, 此时会根据实际数据的个数, 重新创建数组
//2. 如果集合长度 <= 数组长度 ==> 数据放的下, 此时不会创建新的数组, 而是直接用
Map.Entry[] arr1 = entries.toArray(arr);
//相当于: Map.Entry[] arr1 = entries.toArray(new Map.Entry[0]);
//参数接收的是Entry[], 因为可变参数实际上就是一个数组
Map map1 = Map.ofEntries(arr1);
System.out.println(map1);//{王五=武汉, 张三=北京, 李四=上海}
}
}toArray()
- 如果集合长度 > 数组长度 ==> 数据在数据中放不下, 此时会根据实际数据的个数, 重新创建数组
- 如果集合长度 <= 数组长度 ==> 数据放的下, 此时不会创建新的数组, 而是直接用
前面所写创建不可变集合Map的方法太过繁琐, 以下是简略写法:
java
Map<Object, Object> map3 = Map.ofEntries(map.entrySet().toArray(new Map.Entry[0]));copyOf的使用
即便使用ofEntries创建对象, 但还是太繁琐了. 在JDk10的时候, 提供了copyOf方法, 此方法只需传入一个Map集合便可以返回不可变Map.
java
HashMap<String, String> map = new HashMap<>();
map.put("张三", "北京");
map.put("李四", "上海");
map.put("王五", "武汉");
//创建不可变集合Map, 但
Map<String, String> map4 = Map.copyOf(map);