比如我们想创建一个 list 集合,想让这个 list 不能在被做任何修改了,这时候我们就可以用 Guava 包里 ImmutableSet 来创建一个 list
例子:
不可变集合有哪些好处呢?
public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of(
"red",
"orange",
"yellow",
"green",
"blue",
"purple");
当对象被不可信的库调用时,不可变形式是安全的;(可以交给任意逻辑去)
不可变对象被多个线程调用时,不存在竞态条件问题(不存在多线程里的线程安全问题)
不可变集合不需要考虑变化,因此可以节省时间和空间.所有不可变的集合都比它们的可变形式有更好的内存利用率(分析和测试细节);(节省空间)
不可变对象因为有固定不变,可以作为常量来安全使用.(作为常量)
不仅 Guava 包提供了不可变集合的版本,jdk 本身也提供了 Collecitons.unmodifiableXXXX 方法来把集合变成不可变的形式,但 JDK 的有以下几个缺点:
笨重累赘,需要写的代码太多了.
不安全,如果通过原集合的引用来进行集合里元素的修改其实也是可以修改的,导致可变了.
效率较低.被包装过的集合本质上还是使用着原来集合的方法,导致比如并发修改 list 还是会有一些检查,HashMap 里还有一些没有用的额外的属性.其实如果集合不可变,原来集合里的一些机制就可以没有了.
重要提示:
所有 Guava 不可变集合的实现都不接受 null 值.我们对 Google 内部的代码库做过详细研究,发现只有 5% 的情况需要在集合中允许 null 元素,剩下的 95% 场景都是遇到 null 值就快速失败.如果你需要在不可变集合中使用 null,请使用 JDK 中的 Collections.unmodifiableXXX 方法.更多细节建议请参考 "使用和避免 null".
如果使用呢?
使用 copyOf 方法,例子:ImmutableSet.copyOf(set)
of 方法,ImmutableSet.of("1","2") 或者 ImmutableMap.of("key1","value1","key2","value2");
Builder 工具,例子:ImmutableXXXX.builder().add().builder();
asList 视图
所有不可变集合都有一个 asList() 方法提供 ImmutableList 视图,来帮助你用列表形式方便地读取集合元素.例如,你可以使用 sortedSet.asList().get(k) 从 ImmutableSortedSet 中读取第 k 个最小元素.
asList() 返回的 ImmutableList 通常是——并不总是——开销稳定的视图实现,而不是简单地把元素拷贝进 List.也就是说,asList 返回的列表视图通常比一般的列表平均性能更好,比如,在底层集合支持的情况下,它总是使用高效的 contains 方法
来源: http://www.jianshu.com/p/840494447c14