优势:java
建立对象的不可变拷贝是一项很好的防护性编程技巧。Guava 为全部 JDK 标准集合类型和 Guava 新集合类型 都提供了简单易用的不可变版本。编程
JDK 也提供了 Collections.unmodifiableXXX 方法把集合包装为不可变形式,但Guava认为不够好:安全
若是你没有修改某个集合的需求,或者但愿某个集合保持不变时,把它防护性地拷贝到不可变集合是个很好的实 践。数据结构
重要提示:全部 Guava 不可变集合的实现都不接受 null 值。咱们对 Google 内部的代码库作过详细研究,发现 只有 5%的状况须要在集合中容许 null 元素,剩下的 95%场景都是遇到 null 值就快速失败。若是你须要在不可 变集合中使用 null,请使用 JDK 中的 Collections.unmodifiableXXX 方法。更多细节建议请参考“使用和避免 null”。并发
// copyOf 方法,如 ImmutableSet.copyOf(set); List<String> list = Arrays.asList("a", "b", "c"); ImmutableSet<String> strings = ImmutableSet.copyOf(list); // of 方法,如 ImmutableSet.of(“a”, “b”, “c”)或 ImmutableMap.of(“a”, 1, “b”, 2); ImmutableSet<String> of = ImmutableSet.of("a", "b", "c", "d", "e"); // Builder 工具 ImmutableSet<String> set = ImmutableSet.<String>builder() .add("a") .add("b") .add("c") .build();
另外,对有序不可变集合来讲,排序是在构造集合的时候完成的,如:工具
ImmutableSortedSet.of("a", "b", "c", "a", "d", "b");
会在构造时就把元素排序为 a, b, c, d。性能
ImmutableXXX.copyOf 方法会尝试在安全的时候避免作拷贝——实际的实现细节不详,但一般来讲是 很智能的,好比:ui
ImmutableSet<String> foobar = ImmutableSet.of("foo", "bar", "baz"); thingamajig(foobar); void thingamajig(Collection<String> collection) { ImmutableList<String> defensiveCopy = ImmutableList.copyOf(collection); ... }
在这段代码中,ImmutableList.copyOf(foobar)会智能地直接返回 foobar.asList(),它是一个 ImmutableSet 的常量时间复杂度的 List 视图。google
做为一种探索,ImmutableXXX.copyOf(ImmutableCollection)会试图对以下状况避免线性时间拷贝:线程
在可能的状况下避免线性拷贝,能够最大限度地减小防护性编程风格所带来的性能开销。
全部不可变集合都有一个 asList()方法提供 ImmutableList 视图,来帮助你用列表形式方便地读取集合元素。例 如,你可使用 sortedSet.asList().get(k)从 ImmutableSortedSet 中读取第 k 个最小元素。
asList()返回的 ImmutableList 一般是——并不老是——开销稳定的视图实现,而不是简单地把元素拷贝进 Lis t。也就是说,asList 返回的列表视图一般比通常的列表平均性能更好,好比,在底层集合支持的状况下,它老是 使用高效的 contains 方法。
可变集合接口 | 属于JDK仍是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 |
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Lists; public class Guava { public static void main(String[] args) { //建立 3钟方式 //一、of方法 ImmutableList<String> immutableList = ImmutableList.of("1", "3", "2"); System.out.println(immutableList); //二、copyOf方法 ImmutableList<Object> immutableList1 = ImmutableList.copyOf(Lists.newArrayList(1, "abc", 3d)); System.out.println(immutableList1); //三、builder构建 ImmutableList<Integer> immutableList2 = ImmutableList.<Integer>builder().add(3).add(5).add(7).build(); System.out.println(immutableList2); ImmutableSet<String> immutableSet = ImmutableSet.of("beibei", "jingjing", "huanhuan"); System.out.println(immutableSet); //不可变集合均可以使用asList方法返回一个ImmutableList视图 ImmutableList<String> immutableSetToList = immutableSet.asList(); System.out.println(immutableSetToList); //会自动排序 ImmutableSortedSet<String> immutableSortedSet = ImmutableSortedSet.of("1", "32", "3"); System.out.println(immutableSortedSet); ImmutableMap<String, Integer> immutableMap = ImmutableMap.of("1", 11, "2", 22); System.out.println(immutableMap); System.out.println(immutableMap.asMultimap()); } }
输出结果: [1, 3, 2] [1, abc, 3.0] [3, 5, 7] [beibei, jingjing, huanhuan] [beibei, jingjing, huanhuan] [1, 3, 32] {1=11, 2=22} {1=[11], 2=[22]}
Guava建立不可变集合的这些方法里,ImmutableList、ImmutableSet、ImmutableSortedSet都是继承了全部集合的父类Collection,建立出来的集合可使用JDK相对应集合的方法,是能够直接赋给JDK相对应集合的。其中ImmutableMap是实现Map接口的。
ImmutableList<String> immutableList = ImmutableList.of("1", "3", "2"); List<String> list = new ArrayList<String>(); list = immutableList; immutableList.get(0);