不可变容器,看着好像在实际的业务中不怎么会用到,但实则不然,相信每个小伙伴都用过,或者看到过下面的代码
Collections.emptyList(); Collections.emptyMap(); 复制代码
今天我们来介绍一下如何使用不可变容器,以及使用时的注意事项
1. JDK不可变容器
java原生提供了一些不可变容器,它们最大的特点就是不支持添加、删除、修改容器内的值
Collections.emptyXxx
空容器
Collections.emptyMap(); Collections.emptyList(); Collections.emptySet(); 复制代码
上面三个是最常用的几个了,通常当我们一个方法的返回结果定义为容器类型时,可能为了避免npe,在返回空容器时,会如此使用
除了上面这几个空的不可变容器之外,还有
UnmodifiableList
UnmodifiableMap
UnmodifiableSet
它们的使用姿势,通常是借助Collections
来实现
List<Integer> list = Collections.unmodifiableList(Arrays.asList(1, 2, 3)); 复制代码
如上面创建的List,就不支持set/remove等修改操作
使用不可变容容器,最大的好处就是基于它的不可修改特性,来实现公用,且不会被污染
- 所以一个自然而然能想到的应用场景就是
全局共享的配置
2. Guava不可变容器
上面是jdk提供的不可变容器,相比较与它们,在实际的项目中,使用Gauva的不可变容器的可能更多
ImmutableXxx
;不可变容器
List<Integer> list = ImmutableList.of(1, 2, 3); Set<Integer> set = ImmutableSet.of(1, 2, 3); Map<String, Integer> map = ImmutableMap.of("hello", 1, "world", 2); 复制代码
上面是最常见的三个容器对应的不可变型
从使用角度来看,初始化非常方便(相比较与jdk版而言)
3. 注意事项
不可变容器虽好,但是使用不当也是很坑的;就我个人的一个观点
- 如果是应用内的接口方法,容器传参,返回容器时,尽量不要使用不可变容器;因为你没办法保证别人拿到你的返回容器之后,会对它进行什么操作
- 如果是对外提供返回结果,特别是null的场景,使用不可变的空容器优于返回null
- 不可变容器,用于全局公用资源,共享配置参数;多线程的数据传递时,属于比较合适的场景