成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

跟著 Guava 學(xué) Java 之 不可變集合

開發(fā) 后端
不可變集合,英文叫 immutable,顧名思義就是說集合是不可被修改的。集合的數(shù)據(jù)項(xiàng)是在創(chuàng)建的時(shí)候提供,并且在整個(gè)生命周期中都不可改變。

什么是不可變集合

不可變集合,英文叫 immutable,顧名思義就是說集合是不可被修改的。集合的數(shù)據(jù)項(xiàng)是在創(chuàng)建的時(shí)候提供,并且在整個(gè)生命周期中都不可改變。

為什么要用不可變集合?

第一:防御性編程需要

我有一個(gè)集合,你拿來使用,鬼知道你會(huì)不會(huì)亂搞,往集合里添加不合適的元素,或者隨便刪除元素,我不放心,對(duì),就是不信你,我的集合我做主,給你個(gè)不可變的吧,這樣你就不可能亂搞我的集合了,我就放心了,不擔(dān)心你的操作給我?guī)盹L(fēng)險(xiǎn) 。官方解釋:防御,defensive programming,聽起來高級(jí)不?

第二:線程安全

沒有買賣就沒有殺害!

集合是不可變的,不讓你有變化,不可能有變化。沒有變化,就沒有競態(tài)條件,多少個(gè)線程來都是一個(gè)樣,安全,就是***安全。

第三:節(jié)省開銷

不需要支持可變性,可以盡量節(jié)省空間和時(shí)間的開銷, 所有的不可變集合實(shí)現(xiàn)都比可變集合更加有效的利用內(nèi)存。

JDK9 之前的實(shí)現(xiàn)

Collections提供了一組方法把可變集合封裝成不可變集合:

圖片

但這玩意兒有問題,舉個(gè)例子:

List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");

List<String> unmodifiableList = Collections.unmodifiableList(list);
list.add("d");
System.out.println(unmodifiableList);

這個(gè)輸出的結(jié)果居然是 [a,b,c,d]。

what ? 這不就變了嗎,我要的是不可變集合啊,這坑爹的玩意兒。有兄弟說了,那我切斷 list 的引用是不就行了?

List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");

List<String> unmodifiableList = Collections.unmodifiableList(list);
list.add("d");
list = null;
System.out.println(unmodifiableList);

呵呵,不行,輸出仍然是  [a,b,c,d]  果然坑爹,而且你發(fā)現(xiàn)沒有,編碼也比較麻煩,還得用 Collections 間接轉(zhuǎn)一下。

Collections.unmodifiableList 實(shí)現(xiàn)的不是真正的不可變集合,當(dāng)原始集合修改后,不可變集合也發(fā)生變化。此外,它返回的數(shù)據(jù)結(jié)構(gòu)本質(zhì)仍舊是原來的集合類,所以它的操作開銷,包括并發(fā)下修改檢查,hash table 里的額外數(shù)據(jù)空間都和原來的集合是一樣的。

由于這些問題,JDK9 出了些新的生成不可變集合的方法,比如:

  • List.of
  • Set.of
  • Map.of
  • ......

確實(shí)可以直接生成不可變集合,編碼也比較方便了:

List<String> immutableList= List.of("a", "b", "c");

如果你要修改集合會(huì)拋出異常 java.lang.UnsupportedOperationException:

immutableList.add("d");

but;

List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");

List<List<String>> list1 = List.of(list);
list.add("d");
System.out.println(list1);

上面代碼的輸出仍然是 : [a,b,c,d];

當(dāng)然我們不是說人家 api 是錯(cuò)的,人家就是這么設(shè)計(jì)的(愛信不信),可我感覺不爽,如果不小心可能會(huì)犯錯(cuò),本來是防御性編程,搞不好干成跑路性編程了。

再次強(qiáng)調(diào),不是說人家 JDK 設(shè)計(jì)錯(cuò)了,人家就是這么設(shè)計(jì)的,你的明白?當(dāng)然不爽的還有 google 的工程師們,所以我們下面介紹下拿起鍵盤自己解決問題的 google 工程師們寫的 guava 是怎么解決問題的。

Guava

來,我們接著上面的那個(gè)例子,直接寫個(gè) Guava 版本的你自己體會(huì)下:

List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");

ImmutableList<String> strings = ImmutableList.copyOf(list);
list.add("d");

System.out.println(strings);

輸出終于如我所愿的是 : [a,b,c] 了。

無論是從命名、語義、結(jié)果、代碼可讀性是不是都比 JDK 版本的好很多?這樣的代碼讓我感覺世界又美好了一些。

美好的東西都想擁有,但問題來了, Guava 針對(duì)哪些集合提供了哪些對(duì)應(yīng)的不可變集合類呢,這里我們給大家整理了一下:

可變集合接口

屬于 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

介紹幾個(gè)方法:

  • of 方法,用法是一脈相承的,就是構(gòu)建集合用的
  • copyOf ,上面例子中出現(xiàn)過,官方文檔上說它是智能的,比如它可以判斷參數(shù)是不是一個(gè) immutable 對(duì)象,這樣可以避免做拷貝

JDK10

List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");

List<String> strings = List.copyOf(list);

list.add("d");
System.out.println(strings);

以上代碼在 JDK10 以上版本輸出  :[a,b,c],主要是因?yàn)?copyOf 方法是 10 以上版本才有的。

你看,JDK 也一直在進(jìn)步,所以如果你用的是 JDK10 以及上版本,是不是要用 Guava 在這個(gè)具體功能點(diǎn)上就是可選的了。

最后

整體對(duì)比起來,我的個(gè)人感覺是在不可變集合的操作上 Guava 的 API 更好用一些,當(dāng)然庫的使用因人而異,用 JDK 原生的也沒毛病,畢竟依賴更少,學(xué)習(xí)成本也小。

我們總說要改革、要進(jìn)步,而真正的改革往往都不是自上而下的,很多都是自下而上的被推動(dòng)著前進(jìn) ,如果沒有 Guava,沒有開源社區(qū)的很多優(yōu)秀的庫和組件,JDK 會(huì)不會(huì)把這些優(yōu)秀的建議吸取進(jìn)來?我不知道,但至少 JAVA 也一直在進(jìn)步,也希望它越來越好。

責(zé)任編輯:武曉燕 來源: 小盒子的技術(shù)分享
相關(guān)推薦

2022-02-09 07:52:36

GolangGo語言

2023-10-20 08:18:17

Python數(shù)據(jù)類型

2022-09-21 08:16:18

緩存框架

2022-08-19 19:02:20

開源鴻蒙操作系統(tǒng)

2023-06-07 19:17:14

UbuntuKDELinux

2024-02-26 10:47:09

Python數(shù)據(jù)類型開發(fā)

2024-04-08 07:58:11

Python數(shù)據(jù)類型字符串

2010-01-14 14:30:09

VB.NET匿名類型

2015-10-12 08:56:27

Java不可變

2022-06-28 09:10:32

K8S容器鏡像滾動(dòng)升級(jí)

2015-03-19 15:04:06

2017-04-02 09:30:15

機(jī)器人駕校機(jī)器人教學(xué)

2023-02-18 13:47:04

CoreOS容器操作系統(tǒng)云原生

2022-02-07 10:21:54

.NET配置對(duì)象

2021-06-14 09:34:23

對(duì)象存儲(chǔ)存儲(chǔ)

2020-03-09 10:21:12

Java集合類 Guava

2022-08-29 17:25:19

鴻蒙應(yīng)用開發(fā)

2025-02-08 13:23:27

JavaScript開發(fā)喚醒鎖

2021-04-07 17:06:55

String Final存儲(chǔ)

2024-09-24 08:36:18

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲精品免费视频 | 亚洲精品在线视频 | 一区二区三区免费 | 免费视频一区二区 | 亚洲成人一区 | 一级在线毛片 | 一区二区三区视频在线观看 | 国产精品福利在线观看 | 99精品观看 | 亚洲日韩中文字幕一区 | 婷婷亚洲综合 | 超碰在线97国产 | 亚洲视频三区 | 成人免费看黄网站在线观看 | 久久精品欧美电影 | 午夜精品一区二区三区在线视频 | 欧美一级在线免费 | 亚洲精品视频在线看 | 天天操欧美 | 色综合一区二区 | 精品亚洲一区二区 | 欧美精品一区二区在线观看 | 精品视频久久久 | 国产精品福利视频 | 久草福利 | 国产精品揄拍一区二区 | 男女精品网站 | 国产精品色哟哟网站 | 日本小视频网站 | 精品欧美一区二区在线观看欧美熟 | 国产成人精品午夜视频免费 | 久久精品视频99 | 亚洲精品自在在线观看 | 天天做日日做 | 亚洲国产精品99久久久久久久久 | 高清亚洲 | a级毛片毛片免费观看久潮喷 | 久久久久久久国产精品影院 | 国产乱码久久久 | 日韩综合在线视频 | 国产av毛片 |