偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

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

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

什么是不可變集合

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

為什么要用不可變集合?

第一:防御性編程需要

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

第二:線程安全

沒有買賣就沒有殺害!

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

第三:節(jié)省開銷

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

JDK9 之前的實現(xiàn)

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

圖片

但這玩意兒有問題,舉個例子:

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);

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

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

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

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

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

如果你要修改集合會拋出異常 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 是錯的,人家就是這么設(shè)計的(愛信不信),可我感覺不爽,如果不小心可能會犯錯,本來是防御性編程,搞不好干成跑路性編程了。

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

Guava

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

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 針對哪些集合提供了哪些對應(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

介紹幾個方法:

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

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],主要是因為 copyOf 方法是 10 以上版本才有的。

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

最后

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

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

責(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容器鏡像滾動升級

2015-03-19 15:04:06

2017-04-02 09:30:15

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

2023-02-18 13:47:04

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

2022-02-07 10:21:54

.NET配置對象

2021-06-14 09:34:23

對象存儲存儲

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存儲

2024-09-24 08:36:18

點贊
收藏

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