如果你想知道什么是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-不可变集合

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值