不可变集合是不可被修改的, 集合的数据项是在创建的时候提供, 并且在整个生命周期中都不可改变.
Immutable对象有以下的优点:
Immutable对象是一个很好的防御编程(defensive programming)的技术实践
JDK自带的Collections.unmodifiableXXX实现的不是真正的不可变集合,当原始集合修改后,不可变集合也发生变化。
List<String> lists = Lists.newArrayList("aa", "bb", "cc");
List<String> unmodifiedLists = Collections.unmodifiableList(lists);
assertEquals(3, unmodifiedLists.size());
lists.add("dd");
assertEquals(4, unmodifiedLists.size());
JDK自带的Collections.unmodifiableXXX实现的不可变集合存在问题:
com.google.common.collect.ImmutableXXX
ImmutableSet.copyOf(set); // 使用copyOf方法
ImmutableSet.of("a", "b", "c"); // 使用of方法
ImmutableMap.of("a", 1, "b", 2); // 使用of方法
ImmutableSet.<Color>builder() // 使用builder
.add(new Color(0, 255, 255))
.add(new Color(0, 191, 255))
.build();
一般来说,ImmutableXXX.copyOf(ImmutableCollection)会避免线性复杂度的拷贝操作:
这些特性有助于最优化防御性编程的性能开销
所有的immutable集合都以asList()的形式提供了ImmutableList视图(view).
比如,你把数据放在ImmutableSortedSet,你就可以调用sortedSet.asList().get(k)来取得第k个元素的集合。
返回的ImmutableList常常是个常数复杂度的视图,而不是一个真的拷贝。
可变类型集合 | 来源 | Guava中的不可变集合 |
Collection | JDK | ImmutableCollection |
List | JDK | ImmutableList |
Set | JDK | ImmutableSet |
SortedSet/NavigableSet | JDK | ImmutableSortedSet |
Map | JDK | ImmutableMap |
SortedMap | JDK | ImmutableSortedMap |
Multiset | Guava | ImmutableMultiset |
SortedMultiset | Guava | ImmutableSortedMultiset |
Multimap | Guava | ImmutableMultimap |
ListMultimap | Guava | ImmutableListMultimap |
SetMultimap | Guava | ImmutableSetMultimap |
BiMap | Guava | ImmutableBiMap |
ClassToInstanceMap | Guava | ImmutableClassToInstanceMap |
Table | Guava | ImmutableTable |