guava是google的一個庫,彌補了java語言的不少方面的不足,不少在java8中已有實現,暫時不展開。Collections是jdk提供的一個工具類。html
Guava中不可變對象和Collections工具類的unmodifiableSet/List/Map/etc的區別:java
當Collections建立的不可變集合的wrapper類改變的時候,不可變集合也會改變,而Guava的Immutable集合保證確實是不可變的。編程
在JDK中提供了Collections.unmodifiableXXX系列方法來實現不可變集合, 可是存在一些問題,下面咱們先看一個具體實例:app
public class ImmutableTest { @Test public void testJDKImmutable(){ List<String> list=new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); //經過list建立一個不可變的unmodifiableList集合 List<String> unmodifiableList=Collections.unmodifiableList(list); System.out.println(unmodifiableList); //經過list添加元素 list.add("ddd"); System.out.println("往list添加一個元素:"+list); System.out.println("經過list添加元素以後的unmodifiableList:"+unmodifiableList); //經過unmodifiableList添加元素 unmodifiableList.add("eee"); System.out.println("往unmodifiableList添加一個元素:"+unmodifiableList); } }
運行結果:工具
經過運行結果咱們能夠看出:雖然unmodifiableList不能夠直接添加元素,可是個人list是能夠添加元素的,而list的改變也會使unmodifiableList改變。post
因此說Collections.unmodifiableList實現的不是真正的不可變集合。學習
Guava提供了對JDK裏標準集合類裏的immutable版本的簡單方便的實現,以及Guava本身的一些專門集合類的immutable實現。當你不但願修改一個集合類,ui
或者想作一個常量集合類的時候,使用immutable集合類就是一個最佳的編程實踐。 google
注意:每一個Guava immutable集合類的實現都拒絕null值。咱們作過對Google內部代碼的全面的調查,而且發現只有5%的狀況下集合類容許null值,而95%的狀況下url
都拒絕null值。萬一你真的須要能接受null值的集合類,你能夠考慮用Collections.unmodifiableXXX。
immutable集合能夠有如下幾種方式來建立:
一、用copyOf方法, 譬如, ImmutableSet.copyOf(set)
二、使用of方法,譬如,ImmutableSet.of("a", "b", "c")或者ImmutableMap.of("a", 1, "b", 2)
三、使用Builder類
舉例:
@Test public void testGuavaImmutable(){ List<String> list=new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); ImmutableList<String> imlist=ImmutableList.copyOf(list); System.out.println("imlist:"+imlist); ImmutableList<String> imOflist=ImmutableList.of("peida","jerry","harry"); System.out.println("imOflist:"+imOflist); ImmutableSortedSet<String> imSortList=ImmutableSortedSet.of("a", "b", "c", "a", "d", "b"); System.out.println("imSortList:"+imSortList); list.add("baby"); //關鍵看這裏是否imlist也添加新元素了 System.out.println("list添加新元素以後看imlist:"+imlist); ImmutableSet<Color> imColorSet = ImmutableSet.<Color>builder() .add(new Color(0, 255, 255)) .add(new Color(0, 191, 255)) .build(); System.out.println("imColorSet:"+imColorSet); }
運行結果:發現imlist並未改變。
對於排序的集合來講有例外,由於元素的順序在構建集合的時候就被固定下來了。譬如,ImmutableSet.of("a", "b", "c", "a", "d", "b"),對於這個集合的遍歷順序來講就是"a", "b", "c", "d"。
copyOf方法比你想象的要智能,ImmutableXXX.copyOf會在合適的狀況下避免拷貝元素的操做-先忽略具體的細節,可是它的實現通常都是很「智能」的。譬如:
@Test public void testCotyOf(){ ImmutableSet<String> imSet=ImmutableSet.of("peida","jerry","harry","lisa"); System.out.println("imSet:"+imSet); //set直接轉list ImmutableList<String> imlist=ImmutableList.copyOf(imSet); System.out.println("imlist:"+imlist); //list直接轉SortedSet ImmutableSortedSet<String> imSortSet=ImmutableSortedSet.copyOf(imSet); System.out.println("imSortSet:"+imSortSet); List<String> list=new ArrayList<String>(); for(int i=0;i<=10;i++){ list.add(i+"x"); } System.out.println("list:"+list); //截取集合部分元素 ImmutableList<String> imInfolist=ImmutableList.copyOf(list.subList(2, 8)); System.out.println("imInfolist:"+imInfolist); }
運行結果
可變集合類型 | 可變集合源:JDK or Guava? | 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 |
本文參考:Guava學習筆記:Immutable(不可變)集合 感謝!
想太多,作太少,中間的落差就是煩惱。想沒有煩惱,要麼別想,要麼多作。中校【12】