前言
Java中创建不可变集合的应用场景:
1.如果某个数据不能被修改,把他防御性地拷贝到不可变集合中是个很好的实践。
2.当集合对象被不可信的库调用时,不可变形式是安全的。
简单来理解就是不想让别人修改集合中的内容的时候,可以用不可变集合。
提示:以下是本篇文章正文内容,下面案例可供参考
不可变集合的创建方式
List和Set的不可变集合创建都比较简单,重点可以看看Map。
public class immutableTest01 {
public static void main(String[] args) {
//不可变的集合:创建完毕之后,是无法进行修改的,只能进行查询操作
//一、创建一个不可变的List集合
List<String> list = List.of("张三", "李四", "王五", "赵六");
for (String str : list){
System.out.print(str + " ");//输出:张三 李四 王五 赵六
}
//修改会报错:Exception in thread "main" java.lang.UnsupportedOperationException
list.add("wubba");
list.remove("张三");
list.set(0,"w");
//二、创建不可变的Set集合的细节:里面的参数一定要保证唯一性
Set<String> set = Set.of("张三", "李四", "王五", "赵六");
for (String str : set){
System.out.print(str + " ");//输出:张三 李四 王五 赵六
}
//修改会报错:Exception in thread "main" java.lang.UnsupportedOperationException
set.remove("张三");
//三、创建Map的不可变集合
/*
细节一:键是不能重复的
细节二:Map里面的of方法,参数是有上限的,最多只能传递20个参数=10个键值对
细节三:如果我们要传递多个键值对对象,数量大于10个,在Map接口中还有一个方法ofEntries
static <K, V> Map<K, V> ofEntries(Entry<? extends K, ? extends V>... entries)
ofEntries:里面是接收Entry对象的可变形参,我们可以把键跟值看作一个整体传递给它
它会给我们返回一个不可变的集合
*/
Map<String, String> map = Map.of("a", "张张", "b", "姜姜", "c", "球球", "d", "七七",
"e", "管管", "f", "比比", "g", "君君", "h", "呜呜",
"i", "康康", "j", "安安");
Set<String> keys = map.keySet();
for(String key : keys){
String value = map.get(key);
//输出:e: 管管 ||d: 七七 ||c: 球球 ||b: 姜姜 ||a: 张张 ||j: 安安 ||i: 康康 ||h: 呜呜 ||g: 君君 ||f: 比比 ||
System.out.print(key + ": " + value + " ||");
}
//修改会报错:Exception in thread "main" java.lang.UnsupportedOperationException
map.put("aa","good");
//如果你想要一个键值对超过10个的map集合的话
//1.创建一个普通的map集合
Map<String, String> m1 = new HashMap<>();
m1.put("a", "张张");
m1.put("b", "姜姜");
m1.put("c", "球球");
m1.put("d", "七七");
m1.put("e", "管管");
m1.put("f", "比比");
m1.put("g", "君君");
m1.put("h", "呜呜");
m1.put("i", "康康");
m1.put("j", "安安");
m1.put("k", "天天");
//2.利用上面的数据来获取一个不可变的集合
//获取到所有的键值对对象(Entry对象)
Set<Map.Entry<String, String>> entries = m1.entrySet();
//把entries变成一个数组
Map.Entry[] arr1 = new Map.Entry[0];
/*
toArray方法接收一个数组对象,就可以把集合变成该数组类型的数组
toArray方法在底层会比较集合的长度跟数组的长度两者的大小
如果集合的长度 > 数组的长度:数据在数组中放不下,就会根据实际数据的个数,重新创建数组
如果集合的长度 <= 数组的长度,数据在数组中放得下,就不会创建新的数组,而是直接使用
*/
Map.Entry[] arr2 = entries.toArray(arr1);
//3.调用Map的ofEntries方法,成功转换成不可变集合
Map m2 = Map.ofEntries(arr2);
m2.put("l","丽丽"); //修改会报错:Exception in thread "main" java.lang.UnsupportedOperationException
//浓缩版转换
Map<Object, Object> m3 = Map.ofEntries(m1.entrySet().toArray(new Map.Entry[0]));
m3.put("qq","kiki"); //修改会报错:Exception in thread "main" java.lang.UnsupportedOperationException
//jdk10以上的可以用下面这个方法,jdk10以下的用上面的方法
/*
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 Map.Entry[0]));
}
}
*/
Map<String, String> m4 = Map.copyOf(m1);
m4.put("oo","lili"); //修改会报错:Exception in thread "main" java.lang.UnsupportedOperationException
}
}