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相关推荐

  1. java如何将两首歌按时间合成,用goldwave怎样把两首歌合并在一起

    类型:音频处理大小:11.3M语言:中文 评分:4.6 标签: 立即下载 goldwave是一款非常好用功能强大的音频编辑软件,用户可以使用goldwave录制.编辑.转换音频,可以进行相应的音频处理 ...

  2. java如何将两首歌按时间合成_怎么制作串烧歌曲?将多首音乐合并成一首音乐的操作方法...

    我怕是过了个假的春天吧,这天气咋就热成这个样子了呢,现在才三月份啊,气温最高就已经达到了20℃~到时候真正的夏天到了又该咋办呢?果然空调是夏天的续命宝物啊哈哈哈.热热的夏天还是要来听自己喜欢的音乐吖, ...

  3. 一首歌的时间看懂荷兰三色旗问题

    给定一个包含红色.白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色.白色.蓝色顺序排列. 此题中,我们使用整数 0. 1 和 2 分别表示红色.白色和蓝色. ...

  4. 如何引入阿里矢量图的具体方法(一首歌的时间即可学会)

    关于阿里矢量图引入的具体方法 第一步:去官网阿里巴巴矢量图标库 拿头像来举例,如下图所示,将鼠标放在图标上面会有三个选项 点击加入购物车,点击(下载代码). 保存到你已经新建好的文件夹.然后解压文件. ...

  5. 如何命令行结束react程序_想要成为前端Star 吗?一首歌时间将React / Vue 应用Docker 化...

    前言 以前一直有疑问困扰着我:人人都在吹的Docker容器化,与前端有何关系? 然而在近两年的编程生涯,在每一次产品迭代中,渐渐体会到了容器化其魅力所在. 应用部署从刀耕火种,到DevOps崛起,原来 ...

  6. docker web程序本地化_想要成为前端Star 吗?一首歌时间将React / Vue 应用Docker 化...

    前言 以前一直有疑问困扰着我:人人都在吹的Docker容器化,与前端有何关系? 然而在近两年的编程生涯,在每一次产品迭代中,渐渐体会到了容器化其魅力所在. 应用部署从刀耕火种,到DevOps崛起,原来 ...

  7. 用一首歌时间将 React 应用 Docker 化,成为前端 Star!

    作者 | 前端劝退师 责编 | 郑丽媛 来源 | 前端劝退师(ID:quantuishi) 以前一直有疑问困扰着我:人人都在吹的Docker容器化,与前端有何关系? 然而在近两年的编程生涯,在每一次产 ...

  8. java唱哪首歌好听_非常非常好听,但是非常非常难找的歌

    1<快乐还是忧伤>(旋律一开始就被迷住了,走过忧伤 告别快乐 留下美丽的心碎记忆) 2<Не говори мне ничего>(老在酒吧听到,俄语中的经典,值得收藏!) 3 ...

  9. [zt]给你的Mp4大换血,精选Touch里3年收集的900多首歌,经典不忍去的最新近流行的,与你共享~~...

    如果你是音乐爱好者:  这些歌, 请戴上耳机, 调大音量, 一个人听 ,全世界 都是你的!!!!! (一)这些歌很温暖,没有金属味,适合有阳光的午后,很悠闲...  [Anaesthesia]Maxi ...

最新文章

  1. Tensorflow源码解析5 -- 图的边 - Tensor
  2. [Python人工智能] 二十三.基于机器学习和TFIDF的情感分类(含详细的NLP数据清洗)
  3. WPF保存包含Winform控件的XAML页面问题
  4. 全网最新Spring Boot2.5.1整合Activiti5.22.0企业实战教程<基础篇>
  5. div默认外边距是多少_CSS 外边距
  6. 又拍云 php5月18号那,又拍云每月免费CDN空间和流量
  7. CocoaPods停在Analyzing dependencies解决方案
  8. 基于wxpython+MySQL--实现人脸检测识别的宿舍人脸检测系统
  9. python-gui-pyqt5的使用方法-3--自定义信号的初识
  10. 怎么把cad的图导入ps_CAD图纸快速高效导入PS的方法
  11. java 解析 ts_解析TS - xxdd的个人空间 - OSCHINA - 中文开源技术交流社区
  12. 五星大饭店韩文插曲-请不要离我而去MV
  13. photo cs6 2018破解教程
  14. Web前端期末大作业--中国港珠澳大桥网页设计(HTML+CSS+JavaScript)实现
  15. 在react框架中实现打印过程中踩的坑
  16. gdb 查看内存 及 变量类型
  17. The MegaFace Benchmark-1 Million Faces for Recognition at Scale
  18. 网络丢包产生的几个原因,总结!
  19. 学生喂养动物(猫,狗,鸟)
  20. postgresql导入导出大文件 copy命令

热门文章

  1. 【差分约束+spfa优化】P3084 [USACO13OPEN]Photo G
  2. vue中使用Lodop调用打印机打印条形码
  3. 【调剂】北京电子科技学院2021年硕士研究生招生复试调剂录取工作方案
  4. 开源H5选择器UI组件——Picker.js
  5. 【STM32编程】一个定时器生成多路PWM波形的原理和方法
  6. Levenberger-Marquardt for nonlinear elliptical system
  7. MySQL表字段类型哪些
  8. oracle数据库日志翻译工具,sql语句翻译工具
  9. Phillip and Trains(dfs专题)
  10. 学习java的第十三天,回顾方法的定义及调用,以及面向对象构造器、类与对象的关系等基础