1. 程式人生 > >【java代碼之美】---guava之Immutable(不可變)集合

【java代碼之美】---guava之Immutable(不可變)集合

實例 bubuko mage string 工具類 clas tle wrapper 系列

Immutable(不可變)集合

一、概述

guava是google的一個庫,彌補了java語言的很多方面的不足,很多在java8中已有實現,暫時不展開。Collections是jdk提供的一個工具類。

Guava中不可變對象和Collections工具類的unmodifiableSet/List/Map/etc的區別:

當Collections創建的不可變集合的wrapper類改變的時候,不可變集合也會改變而Guava的Immutable集合保證確實是不可變的

1、JDK中實現immutable集合

在JDK中提供了Collections.unmodifiableXXX系列方法來實現不可變集合, 但是存在一些問題,下面我們先看一個具體實例:

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改變。

所以說Collections.unmodifiableList實現的不是真正的不可變集合。

2、Guava的immutable集合

Guava提供了對JDK裏標準集合類裏的immutable版本的簡單方便的實現,以及Guava自己的一些專門集合類的immutable實現。當你不希望修改一個集合類,

或者想做一個常量集合類的時候,使用immutable集合類就是一個最佳的編程實踐。

註意:每個Guava immutable集合類的實現都拒絕null值。我們做過對Google內部代碼的全面的調查,並且發現只有5%的情況下集合類允許null值,而95%的情況下

都拒絕null值。萬一你真的需要能接受null值的集合類,你可以考慮用Collections.unmodifiableXXX。

immutable集合可以有以下幾種方式來創建:

  1、用copyOf方法, 譬如, ImmutableSet.copyOf(set)

  2、使用of方法,譬如,ImmutableSet.of("a", "b", "c")或者ImmutableMap.of("a", 1, "b", 2)

  3、使用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

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);
        }

運行結果

技術分享圖片

Guava集合和不可變對應關系

可變集合類型 可變集合源: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】

【java代碼之美】---guava之Immutable(不可變)集合