给我半首歌的时间,给你说明白Immutable List
Immutable List,顾名思义,就是,啥,不明白 Immutable 是什么意思?一成不变的意思,所以 Immutable List 就是一个不可变的 List 类,这意味着该 List 声明后,它的内容就是固定的,不可增删改的。
如果对不可变类比较陌生的话,可以先点击下面的链接查看我之前写的另外一篇文章。
这次要说不明白immutable类,我就怎么地
如果尝试对 List 中的元素进行增加、删除或者更新,就会抛出 UnsupportedOperationException 异常。
另外,Immutable List 中的元素是非 null 的,如果使用 null 来创建 Immutable List,则会抛出 NullPointerException;如果尝试在 Immutable List 中添加 null 元素,则会抛出 UnsupportedOperationException。
那 Immutable List 有什么好处呢?
它是线程安全的;
它是高效的;
因为它是不可变的,就可以像 String 一样传递给第三方类库,不会发生任何安全问题。
那接下来,我们来看一下,如何创建 Immutable List。注意,源码是基于 JDK14 的。
01、借助原生 JDK
Collections 类的 unmodifiableList() 方法可以创建一个类似于 Immutable List 的 UnmodifiableList 或者 UnmodifiableRandomAccessList,都是不可修改的。
public static List unmodifiableList(List<? extends T> list) {
return (list instanceof RandomAccess ?
new Collections.UnmodifiableRandomAccessList<>(list) :
new Collections.UnmodifiableList<>(list));
}
1
2
3
4
5
来看一下使用方法:
List list = new ArrayList<>(Arrays.asList(“沉默王二”, “沉默王三”, “沉默王四”));
List unmodifiableList = Collections.unmodifiableList(list);
1
2
我们尝试往 unmodifiableList 中添加元素“沉默王五”:
unmodifiableList.add(“沉默王五”);
1
运行后会抛出 UnsupportedOperationException 异常:
Exception in thread “main” java.lang.UnsupportedOperationException
at java.base/java.util.Collections$UnmodifiableCollection.add(Collections.java:1062)
at com.cmower.mkyong.immutablelist.ImmutableListDemo.main(ImmutableListDemo.java:16)
1
2
3
02、借助 Java 9
Java 9 的时候,List 类新增了一个 of() 静态工厂方法,可以用来创建不可变的 List。先来看一下源码:
static List of(E e1, E e2, E e3) {
return new ImmutableCollections.ListN<>(e1, e2, e3);
}
1
2
3
of() 方法有很多变体,比如说:
static List of(E e1) {
return new ImmutableCollections.List12<>(e1);
}
static List of(E e1, E e2) {
return new ImmutableCollections.List12<>(e1, e2);
}
static List of(E e1, E e2, E e3, E e4) {
return new ImmutableCollections.ListN<>(e1, e2, e3, e4);
}
static List of(E e1, E e2, E e3, E e4, E e5) {
return new ImmutableCollections.ListN<>(e1, e2, e3, e4, e5);
}
static List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
return new ImmutableCollections.ListN<>(e1, e2, e3, e4, e5,
e6, e7, e8, e9, e10);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
该方法的设计者也挺有意思的,of() 方法的参数,从 0 到 10 都有一个相同签名的重载方法。
甚至当参数是可变的时候,使用 switch 语句对参数的个数进行了判断,然后调用不同的重载方法:
static List of(E… elements) {
switch (elements.length) { // implicit null check of elements
case 0:
@SuppressWarnings(“unchecked”)
var list = (List) ImmutableCollections.ListN.EMPTY_LIST;
return list;
case 1:
return new ImmutableCollections.List12<>(elements[0]);
case 2:
return new ImmutableCollections.List12<>(elements[0], elements[1]);
default:
return new ImmutableCollections.ListN<>(elements);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
不管是 ImmutableCollections.List12 还是 ImmutableCollections.ListN,它们都是 final 的,并且继承了 AbstractImmutableList,里面的元素也是 final 的。
static final class List12 extends ImmutableCollections.AbstractImmutableList
implements Serializable {
@Stable
private final E e0;@Stable
private final E e1;
}
static final class ListN extends ImmutableCollections.AbstractImmutableList
implements Serializable {
// EMPTY_LIST may be initialized from the CDS archive.
static @Stable List<?> EMPTY_LIST;static {VM.initializeFromArchive(ImmutableCollections.ListN.class);if (EMPTY_LIST == null) {EMPTY_LIST = new ImmutableCollections.ListN<>();}
}@Stable
private final E[] elements;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
好了,来看一下使用方法吧:
final List unmodifiableList = List.of(“沉默王二”, “沉默王三”, “沉默王四”);
unmodifiableList.add(“沉默王五”);
1
2
ImmutableCollections 的内部类 ListN 或者 List12 同样不可修改,使用 add() 方法添加元素同样会在运行时抛出异常:
Exception in thread “main” java.lang.UnsupportedOperationException
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:73)
at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add(ImmutableCollections.java:77)
at com.cmower.mkyong.immutablelist.ImmutableListDemo.main(ImmutableListDemo.java:20)
1
2
3
4
03、借助 Guava
Guava 工程包含了若干被 Google 的 Java 项目广泛依赖的核心库,例如:集合 [collections] 、缓存 [caching] 、原生类型支持 [primitives support] 、并发库 [concurrency libraries] 、通用注解 [common annotations] 、字符串处理 [string processing] 、I/O 等等。 所有这些工具每天都在被 Google 的工程师应用在产品服务中。
在实际的项目实战当中,Guava 类库的使用频率真的蛮高的,因此我们需要在项目中先引入 Guava 的 Maven 依赖。
com.google.guava guava 28.1-jre 1 2 3 4 5 Guava 定了一个 ImmutableList 类,它的声明方式如下所示:
@GwtCompatible(serializable = true, emulated = true)
@SuppressWarnings(“serial”) // we’re overriding default serialization
public abstract class ImmutableList extends ImmutableCollection
implements List, RandomAccess {
}
1
2
3
4
5
它的类结构关系如下所示:
java.lang.Object
↳ java.util.AbstractCollection
↳ com.google.common.collect.ImmutableCollection
↳ com.google.common.collect.ImmutableList
1
2
3
4
ImmutableList 类的 copyOf() 方法可用于创建一个不可变的 List 对象:
List list = new ArrayList<>(Arrays.asList(“沉默王二”, “沉默王三”, “沉默王四”));
List unmodifiableList = ImmutableList.copyOf(list);
unmodifiableList.add(“沉默王五”);
1
2
3
ImmutableList 同样不允许添加元素,add() 方法在执行的时候会抛出 UnsupportedOperationException 异常:
Exception in thread “main” java.lang.UnsupportedOperationException
at com.google.common.collect.ImmutableCollection.add(ImmutableCollection.java:244)
at com.cmower.mkyong.immutablelist.ImmutableListDemo.main(ImmutableListDemo.java:25)
1
2
3
ImmutableList 类的 of() 方法和 Java 9 的 of() 方法类似,同样有很多相同签名的重载方法,使用方法也完全类似:
List unmodifiableList = ImmutableList.of(“沉默王二”, “沉默王三”, “沉默王四”);
1
ImmutableList 类还提供了 builder 模式,既可以在创建的时候添加元素,也可以基于已有的 List 创建,还可以将两者混合在一起。
ImmutableList iList = ImmutableList.builder()
.add(“沉默王二”, “沉默王三”, “沉默王四”)
.build();
List list = List.of(“沉默王二”, “沉默王三”, “沉默王四”);
ImmutableList iList = ImmutableList.builder()
.addAll(list)
.build();
List list = List.of(“沉默王二”, “沉默王三”, “沉默王四”);
ImmutableList iList = ImmutableList.builder()
.addAll(list)
.add(“沉默王五”)
.build();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
04、Collections.unmodifiableList() 和 ImmutableList 有什么区别?
Collections.unmodifiableList() 基于原有的 List 创建了一个不可变的包装器,该包装器是不可修改的,但是,我们可以通过对原有的 List 进行修改,从而影响到包装器,来看下面的示例:
List list = new ArrayList<>();
list.add(“沉默王二”);
List iList = Collections.unmodifiableList(list);
list.add(“沉默王三”);
list.add(“沉默王四”);
System.out.println(iList);
1
2
3
4
5
6
7
8
9
程序输出的结果如下所示:
[沉默王二, 沉默王三, 沉默王四]
1
但如果我们通过 ImmutableList 类创建一个不可变 List,原有 List 的改变并不会影响到 ImmutableList。
List list = new ArrayList<>();
list.add(“沉默王二”);
ImmutableList iList = ImmutableList.copyOf(list);
list.add(“沉默王三”);
list.add(“沉默王四”);
System.out.println(iList);
1
2
3
4
5
6
7
8
9
程序输出的结果如下所示:
[沉默王二]
1
这是因为 ImmutableList 是在原有的 List 上进行了拷贝。
我是沉默王二,一枚有颜值却靠才华苟且的程序员。关注即可提升学习效率,别忘了三连啊,点赞、收藏、留言,我不挑,奥利给。
注:如果文章有任何问题,欢迎毫不留情地指正。
如果你觉得文章对你有些帮助欢迎微信搜索「沉默王二」第一时间阅读,回复「小白」更有我肝了 4 万+字的 Java 小白手册 2.0 版,本文 GitHub github.com/itwanger 已收录,欢迎 star。
————————————————
版权声明:本文为CSDN博主「沉默王二」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qing_gee/article/details/107611560
给我半首歌的时间,给你说明白Immutable List相关推荐
- java如何将两首歌按时间合成,用goldwave怎样把两首歌合并在一起
类型:音频处理大小:11.3M语言:中文 评分:4.6 标签: 立即下载 goldwave是一款非常好用功能强大的音频编辑软件,用户可以使用goldwave录制.编辑.转换音频,可以进行相应的音频处理 ...
- java如何将两首歌按时间合成_怎么制作串烧歌曲?将多首音乐合并成一首音乐的操作方法...
我怕是过了个假的春天吧,这天气咋就热成这个样子了呢,现在才三月份啊,气温最高就已经达到了20℃~到时候真正的夏天到了又该咋办呢?果然空调是夏天的续命宝物啊哈哈哈.热热的夏天还是要来听自己喜欢的音乐吖, ...
- 一首歌的时间看懂荷兰三色旗问题
给定一个包含红色.白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色.白色.蓝色顺序排列. 此题中,我们使用整数 0. 1 和 2 分别表示红色.白色和蓝色. ...
- 如何引入阿里矢量图的具体方法(一首歌的时间即可学会)
关于阿里矢量图引入的具体方法 第一步:去官网阿里巴巴矢量图标库 拿头像来举例,如下图所示,将鼠标放在图标上面会有三个选项 点击加入购物车,点击(下载代码). 保存到你已经新建好的文件夹.然后解压文件. ...
- 如何命令行结束react程序_想要成为前端Star 吗?一首歌时间将React / Vue 应用Docker 化...
前言 以前一直有疑问困扰着我:人人都在吹的Docker容器化,与前端有何关系? 然而在近两年的编程生涯,在每一次产品迭代中,渐渐体会到了容器化其魅力所在. 应用部署从刀耕火种,到DevOps崛起,原来 ...
- docker web程序本地化_想要成为前端Star 吗?一首歌时间将React / Vue 应用Docker 化...
前言 以前一直有疑问困扰着我:人人都在吹的Docker容器化,与前端有何关系? 然而在近两年的编程生涯,在每一次产品迭代中,渐渐体会到了容器化其魅力所在. 应用部署从刀耕火种,到DevOps崛起,原来 ...
- 用一首歌时间将 React 应用 Docker 化,成为前端 Star!
作者 | 前端劝退师 责编 | 郑丽媛 来源 | 前端劝退师(ID:quantuishi) 以前一直有疑问困扰着我:人人都在吹的Docker容器化,与前端有何关系? 然而在近两年的编程生涯,在每一次产 ...
- java唱哪首歌好听_非常非常好听,但是非常非常难找的歌
1<快乐还是忧伤>(旋律一开始就被迷住了,走过忧伤 告别快乐 留下美丽的心碎记忆) 2<Не говори мне ничего>(老在酒吧听到,俄语中的经典,值得收藏!) 3 ...
- [zt]给你的Mp4大换血,精选Touch里3年收集的900多首歌,经典不忍去的最新近流行的,与你共享~~...
如果你是音乐爱好者: 这些歌, 请戴上耳机, 调大音量, 一个人听 ,全世界 都是你的!!!!! (一)这些歌很温暖,没有金属味,适合有阳光的午后,很悠闲... [Anaesthesia]Maxi ...
最新文章
- Tensorflow源码解析5 -- 图的边 - Tensor
- [Python人工智能] 二十三.基于机器学习和TFIDF的情感分类(含详细的NLP数据清洗)
- WPF保存包含Winform控件的XAML页面问题
- 全网最新Spring Boot2.5.1整合Activiti5.22.0企业实战教程<基础篇>
- div默认外边距是多少_CSS 外边距
- 又拍云 php5月18号那,又拍云每月免费CDN空间和流量
- CocoaPods停在Analyzing dependencies解决方案
- 基于wxpython+MySQL--实现人脸检测识别的宿舍人脸检测系统
- python-gui-pyqt5的使用方法-3--自定义信号的初识
- 怎么把cad的图导入ps_CAD图纸快速高效导入PS的方法
- java 解析 ts_解析TS - xxdd的个人空间 - OSCHINA - 中文开源技术交流社区
- 五星大饭店韩文插曲-请不要离我而去MV
- photo cs6 2018破解教程
- Web前端期末大作业--中国港珠澳大桥网页设计(HTML+CSS+JavaScript)实现
- 在react框架中实现打印过程中踩的坑
- gdb 查看内存 及 变量类型
- The MegaFace Benchmark-1 Million Faces for Recognition at Scale
- 网络丢包产生的几个原因,总结!
- 学生喂养动物(猫,狗,鸟)
- postgresql导入导出大文件 copy命令
热门文章
- 【差分约束+spfa优化】P3084 [USACO13OPEN]Photo G
- vue中使用Lodop调用打印机打印条形码
- 【调剂】北京电子科技学院2021年硕士研究生招生复试调剂录取工作方案
- 开源H5选择器UI组件——Picker.js
- 【STM32编程】一个定时器生成多路PWM波形的原理和方法
- Levenberger-Marquardt for nonlinear elliptical system
- MySQL表字段类型哪些
- oracle数据库日志翻译工具,sql语句翻译工具
- Phillip and Trains(dfs专题)
- 学习java的第十三天,回顾方法的定义及调用,以及面向对象构造器、类与对象的关系等基础