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 |
反倒是
003-guava 集合-不可变集合的更多相关文章
- [Google Guava] 2.1-不可变集合
范例 01 public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of( 02 "red&quo ...
- Java源码分析:Guava之不可变集合ImmutableMap的源码分析
一.案例场景 遇到过这样的场景,在定义一个static修饰的Map时,使用了大量的put()方法赋值,就类似这样-- public static final Map<String,String& ...
- Guava Immutable 不可变集合
Immutable是为了创建不可变集合使用,不可变集合在很多情况下能提高系统性能.一般使用 .of()或者.builder()<>().put().build()初始化创建不可变集合
- Guava学习笔记:Immutable(不可变)集合
不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对象有以下的优点: 1.对不可靠的客 ...
- java代码之美(4)---guava之Immutable(不可变)集合
Immutable(不可变)集合 一.概述 guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开.Collections是jdk提供的一个工具类 ...
- Immutable(不可变)集合
Immutable(不可变)集合 不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对 ...
- Java中的不可变集合,我们换个方式理解!!!
不可变集合例: public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of( "red" ...
- Object-C,NSSet,不可变集合
又到晚上了,继续码代码. 正在此时,老爸一个电话"海阔凭鱼跃,天高任鸟飞",老爸不在为老问题烦我了. 自由了,突然感觉压力好大啊. 将来混的太惨,可咋办啊- 第1个例子是,不可变集 ...
- 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?
==知识梳理== ==重难点梳理== ==今日目标== 1.能够了解什么是可变参数 2.能够了解如何去创建不可变集合 3.能够掌握Stream流的使用 ==知识点== 1.可变参数 2.Stream流 ...
随机推荐
- linux系统编程之进程(一)
今天起,开始学习linux系统编程中的另一个新的知识点----进程,在学习进程之前,有很多关于进程的概念需要了解,但是,概念是很枯燥的,也是让人很容易迷糊的,所以,先抛开这些抽象的概念,以实际编码来熟 ...
- 微信小程序API~用户信息
UserInfo 用户信息 属性 string nickName 用户昵称 string avatarUrl 用户头像图片的 URL.URL 最后一个数值代表正方形头像大小(有 0.46.64.96. ...
- 《少年先疯队》第八次团队作业:Alpha冲刺第一天
前言 第一天冲刺会议 时间:2019.6.14 地点:9C406 1.1 今日完成任务情况以及遇到的问题. 1.1.1今日完成任务情况 姚玉婷:管理员登录功能的实现,用户登录功能的实现 ...
- *JavaScript标准参考教程 - 阮一峰
参考 页向对象编程的模式(继承&模块化)
- HtmlAgilityPack解析html文档
一.概述 HtmlAgilityPack(以下简称HAP)是一个基于.Net的.第三方免费开源的微型类库,主要用于在服务器端解析html文档. HtmlAgilityPack为网页提供了标准的DOM ...
- git 删除错误commit
其实就是硬reset到之前对的commit记录然后强行再推送到远程库一下 具体操作: git reset --hard <commit_id> git push origin HEAD - ...
- Linux 文件系统缓存 -针对不同数据库有不同作用
文件系统缓存 filesystem cache 许多人没有意识到.文件系统缓存对于性能的影响.Linux系统默认的设置倾向于把内存尽可能的用于文件cache,所以在一台大内存机器上,往往我们可能发现没 ...
- 如何选择梯度下降法中的学习速率α(Gradient Descent Learning Rate Alpha)
梯度下降算法的任务是寻找参数θ,使之能够最小化损失函数. 那么梯度下降法中的学习速率α应该如何选择呢?通常我们画出损失函数随迭代次数增加而变化的曲线. 可能会得到如下的一条曲线,x轴表示迭代次数,y轴 ...
- Pro自定义数据源原理
1. 概念 Connector:定义连接到一个数据源的连接信息,用于创建datastore. Datastore:代表一个数据源的实例,用于打开一个或多个tables或feature class. ...
- golang go程和出让时间片
golang go程和出让时间片 func main() { go func(){ //创建一个子go程 ;i<;i++{ fmt.Println("--------fuck U--- ...