• 003-guava 集合-不可变集合


    一、概述

    二、使用

    2.1、不可变集合

    1、为什么使用不可变集合

    不可变对象有很多优点,包括:

    当对象被不可信的库调用时,不可变形式是安全的;
    不可变对象被多个线程调用时,不存在竞态条件问题
    不可变集合不需要考虑变化,因此可以节省时间和空间。所有不可变的集合都比它们的可变形式有更好的内存利用率(分析和测试细节);
    不可变对象因为有固定不变,可以作为常量来安全使用。

    所有Guava不可变集合的实现都不接受null值。我们对Google内部的代码库做过详细研究,发现只有5%的情况需要在集合中允许null元素,剩下的95%场景都是遇到null值就快速失败。如果你需要在不可变集合中使用null,请使用JDK中的Collections.unmodifiableXXX方法。更多细节建议请参考“使用和避免null”。

    2、JDK中的Collections.unmodifiableXXX方法

        // jdk
        @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);
        }

    输出

    [a, b, c]
    往list添加一个元素:[a, b, c, ddd]
    通过list添加元素之后的unmodifiableList:[a, b, c, ddd]
    
    java.lang.UnsupportedOperationException
        at java.util.Collections$UnmodifiableCollection.add(Collections.java:1055)

    通过运行结果我们可以看出:虽然unmodifiableList不可以直接添加元素,但是我的list是可以添加元素的,而list的改变也会使unmodifiableList改变。

    所以说Collections.unmodifiableList实现的不是真正的不可变集合。

    3、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.copyOf
            ImmutableList<String> imlist=ImmutableList.copyOf(list);
            System.out.println("imlist:"+imlist);
    
            //ImmutableList.of
            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:[a, b, c]
    imOflist:[peida, jerry, harry]
    imSortList:[a, b, c, d]
    list添加新元素之后看imlist:[a, b, c]
    imColorSet:[java.awt.Color[r=0,g=255,b=255], java.awt.Color[r=0,g=191,b=255]]

    智能的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);
        }

    关联可变集合和不可变集合

    可变集合接口 属于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

    反倒是

  • 相关阅读:
    C++ 二元作用域运算符(::)
    C 桶排序
    C 递归的选择排序
    C 归并算法
    C 可变长实参列表
    C条件编译的一些例子
    C实现将中缀算术式转换成后缀表达式
    Activiti6-数据库配置-dbconfig(学习笔记)
    idea在Terminal中使用maven指令
    Spring Boot的web开发
  • 原文地址:https://www.cnblogs.com/bjlhx/p/11583228.html
Copyright © 2020-2023  润新知