一、概述

二、使用

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

反倒是

003-guava 集合-不可变集合的更多相关文章

  1. [Google Guava] 2.1-不可变集合

    范例 01 public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of( 02 "red&quo ...

  2. Java源码分析:Guava之不可变集合ImmutableMap的源码分析

    一.案例场景 遇到过这样的场景,在定义一个static修饰的Map时,使用了大量的put()方法赋值,就类似这样-- public static final Map<String,String& ...

  3. Guava Immutable 不可变集合

    Immutable是为了创建不可变集合使用,不可变集合在很多情况下能提高系统性能.一般使用 .of()或者.builder()<>().put().build()初始化创建不可变集合

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

    不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对象有以下的优点: 1.对不可靠的客 ...

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

    Immutable(不可变)集合 一.概述 guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开.Collections是jdk提供的一个工具类 ...

  6. Immutable(不可变)集合

    Immutable(不可变)集合 不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对 ...

  7. Java中的不可变集合,我们换个方式理解!!!

    不可变集合例: public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of( "red" ...

  8. Object-C,NSSet,不可变集合

    又到晚上了,继续码代码. 正在此时,老爸一个电话"海阔凭鱼跃,天高任鸟飞",老爸不在为老问题烦我了. 自由了,突然感觉压力好大啊. 将来混的太惨,可咋办啊- 第1个例子是,不可变集 ...

  9. 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?

    ==知识梳理== ==重难点梳理== ==今日目标== 1.能够了解什么是可变参数 2.能够了解如何去创建不可变集合 3.能够掌握Stream流的使用 ==知识点== 1.可变参数 2.Stream流 ...

随机推荐

  1. golang log 使用

    原文:https://www.jianshu.com/p/d634316a9487 --------------------------------------------- 在我们开发程序后,如果有 ...

  2. P1341 无序字母对[欧拉路]

    题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 解析 毒瘤字符串读入 我就是不喜欢邻接 ...

  3. HihoCoder1236 Scores

    Scores 求五维偏序(≤).强制在线. \(n,q\le 50000\) 烂大街的题解 考虑如果我们能用bitset找到每一维有哪些比询问点小,然后把每一维的结果取交集,得到的就是答案了. 然后对 ...

  4. C# 8.0 的新特性( NET Framework 4.8 与 Visual Studio 2019 )

    C#8.0 于 2019年4月 随 .NET Framework 4.8 与 Visual Studio 2019 一同发布 使用VS2019体检C#8.0新功能: 编辑.csproj文件,添加如下代 ...

  5. java中split函数参数特殊字符的处理(转义),如:"." 、"\"、"|"

    内容介绍 本文主要介绍java中特殊字符做为split函数的参数,如:"." ."\"."|",双引号等,不能正确分隔源字符串的处理方法. ...

  6. js获取当前时间往后加6天

    获取当前时间往后加6天,并绑定星期几(星期几是最笨的的方法,一个一个判读),后期在优化 <!DOCTYPE html> <html lang="en"> & ...

  7. 面试官常问的20道Java题目(附答案)-来自Java1234

    1. 以下代码的输出结果是(A) int i =3; i = i++; System.out.println(i); A .3  B.4  C.5 a=b++是先将b值赋值给a后b再自增. 2. Ma ...

  8. 010——MATLAB运行错误跳到下一个循环

    (一)MATLAB运行错误跳到下一个循环 :%文件的个数 try %运行的程序放到这里 catch continue%假如上面的没法执行则执行continue,到下个循环 end

  9. Oracle CAST() 函数 数据类型的转换

    CAST()函数可以进行数据类型的转换. CAST()函数的参数有两部分,源值和目标数据类型,中间用AS关键字分隔. 以下例子均通过本人测试. 一.转换列或值 语法:cast( 列名/值 as 数据类 ...

  10. Kubernetes 学习10 Service资源

    一.Service对应组件关系 1.在kubernetes平台之上,pod是有生命周期的,所以为了能够给对应的客户端提供一个固定的访问端点,因此我们在客户端和服务Pod之间添加一个固定的中间层,这个中 ...