如果你想知道什么是Guava不可变集合,那我就带你研究

Posted c.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果你想知道什么是Guava不可变集合,那我就带你研究相关的知识,希望对你有一定的参考价值。

如果你想知道什么是Guava不可变集合,那我就带你研究

Guava是一组来自谷歌的核心Java库,其中包括新的集合类型(比如multimap射和multiset)、不可变集合、并发、I/O、散列、缓存、字符串等的实用工具。它在谷歌中的大多数Java项目中被广泛使用,也被许多其他公司广泛使用

今天我们就来看一下Guava的不可变集合(Immutable Collections)

不可变集合,顾名思义就是说集合是不可被修改的。集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变。

为什么要用immutable对象?immutable对象有以下的优点:

  1. 对不可靠的客户代码库来说,它使用安全,可以在未受信任的类库中安全的使用这些对象
  2. 线程安全的:immutable对象在多线程下安全,没有竞态条件
  3. 不需要支持可变性, 可以尽量节省空间和时间的开销. > 所有的不可变集合实现都比可变集合更加有效的利用内存 (analysis)
  4. 可以被使用为一个常量,并且期望在未来也是保持不变的

immutable对象可以很自然地用作常量,因为它们天生就是不可变的对于immutable对象的运用来说,它是一个很好的防御编程(defensive programming)的技术实践。

参考:Guava学习笔记:Immutable(不可变)集合

JDK中提供了Collections.unmodifiableXXX

在JDK中提供了Collections.unmodifiableXXX系列方法来实现不可变集合, 但是存在一些问题。

Collections.unmodifiableList实现的不是真正的不可变集合,当原始集合修改后,不可变集合也发生变化。不可变集合不可以修改集合数据,当强制修改时会报错。

总结一下JDK的Collections.unmodifiableXXX方法实现不可变集合的一些问题:

  1. 它用起来笨拙繁琐你不得不在每个防御性编程拷贝的地方用这个方法
  2. 它不安全:如果有对象reference原始的被封装的集合类,这些方法返回的集合也就不是正真的不可改变。
  3. 效率低:因为它返回的数据结构本质仍旧是原来的集合类,所以它的操作开销,包括并发下修改检查,hash table里的额外数据空间都和原来的集合是一样的。

参考:Guava学习笔记:Immutable(不可变)集合

对JDK中提供的不可变集合还有不太明白的同学,可以看我上一遍博文《JDK中提供的不可变集合真的做到了不可变吗?》

Guava中不可变集合的使用方法

Guava提供了对JDK里标准集合类里的immutable版本的简单方便的实现,以及Guava自己的一些专门集合类的immutable实现。当你不希望修改一个集合类,或者想做一个常量集合类的时候,使用immutable集合类就是一个最佳的编程实践。

注意:每个Guava immutable集合类的实现都拒绝null值。万一你真的需要能接受null值的集合类,你可以考虑用Collections.unmodifiableXXX。

     @Test
    void test01() {
        ImmutableList<Integer> list = ImmutableList.of(1, 2, null);
        System.out.println(list);
    }

这种情况下会报java.lang.NullPointerException: at index 2

因为Guava immutable集合类在构造的时候会检查null值

    private static <E> ImmutableList<E> construct(Object... elements) {
        return asImmutableList(ObjectArrays.checkElementsNotNull(elements));
    }

接下来介绍一下创建Guava immutable集合的几种方式。

of方法

     @Test
    void test01() {
        ImmutableList<Integer> list = ImmutableList.of(1, 2, 3);
        System.out.println(list);
    }

copyOf方法

基于已有的集合创建不可变集合

    @Test
    void test02() {
        List<String> list  = new ArrayList<String>();
        list.add("a");
        list.add("b");
        list.add("c");
        ImmutableList<String> immutableList = ImmutableList.copyOf(list);
        System.out.println(immutableList);//[a, b, c]
        list.add("d");
        System.out.println(immutableList); //改变原来的list不会改变immutableList [a, b, c]
    }
    @Test
    void test03() {
        Integer[] array = {1, 2, 3, 4, 5};
        System.out.println(ImmutableList.copyOf(array));
    }

Builder方法

    @Test
    public void test04() {
        ImmutableList<Integer> list = ImmutableList.<Integer>builder()
                .add(1)
                .add(2, 3, 4).addAll(Arrays.asList(5, 6))
                .build();
        System.out.println(list);//[1, 2, 3, 4, 5, 6]
    }

可变集合与不可变集合对照表

可变集合类型可变集合源:JDK or Guava?Guava不可变集合
CollectionJDKImmutableCollection
ListJDKImmutableList
SetJDKImmutableSet
ImmutableSortedSetJDKImmutableSortedSet
MapJDKImmutableMap
MultisetGuavaImmutableMultiset
SortedMultisetGuavaImmutableSortedMultiset
MultimapGuavaImmutableMultimap
ListMultimapGuavaImmutableListMultimap
SetMultimapGuavaImmutableSetMultimap
BiMapGuavaImmutableBiMap
ClassToInstanceMapGuavaImmutableClassToInstanceMap
TableGuavaImmutableTable

参考资料

Guava学习笔记:Immutable(不可变)集合

Guava系列之不可变集合

理解不可变集合 | Guava Immutable与JDK unmodifiableList

[Google Guava] 2.1-不可变集合

以上是关于如果你想知道什么是Guava不可变集合,那我就带你研究的主要内容,如果未能解决你的问题,请参考以下文章

java代码之美---guava之Immutable(不可变)集合

关于js中值的比较规则问题

关于js中值的比较规则问题

不依赖 GulpBabelWebPack,还能优雅地写代码吗?

Google Guava 集合(Collections)

[Google Guava] 2.1-不可变集合