優勢: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);