Java Collection API增強功能系列之二 List.of、Set.of、Map.of

Java 9集合工廠方法:用List.ofSet.ofMap.of創建安全不可變集合

Java 9引入了革命性的集合工廠方法List.ofSet.ofMap.of,徹底改變了開發者創建小型不可變集合的方式。這些方法不僅語法簡潔,還在安全性和性能上實現了質的飛躍。本文將深入解析這些工廠方法的核心特性,并通過對比傳統方式,展示其在實際開發中的優勢。


一、新工廠方法概覽

1. 方法家族

方法簽名說明示例
List.of(E... elements)創建不可變ListList<String> list = List.of("A", "B");
Set.of(E... elements)創建不可變Set(元素唯一)Set<Integer> set = Set.of(1, 2, 3);
Map.of(K k1, V v1, ...)創建不可變Map(最多10個鍵值對)Map<String, Integer> map = Map.of("a", 1, "b", 2);
Map.ofEntries(Map.Entry...)創建任意數量鍵值對的MapMap.ofEntries(entry("a", 1), entry("b", 2))

二、核心優勢

1. 真正不可變性(vs 偽不可變)

傳統方式的問題

// Java 8的"不可變"集合
List<String> oldList = Collections.unmodifiableList(new ArrayList<>(Arrays.asList("A", "B"))
);
oldList.add("C"); // 運行時拋出UnsupportedOperationException

新方式

List<String> newList = List.of("A", "B");
newList.add("C"); // 編譯期即可通過IDE提示發現問題
特性新工廠方法Collections.unmodifiableList
編譯期類型檢查? 直接拒絕修改操作? 運行時異常
防御原集合修改? 完全獨立? 包裝集合仍受原集合影響

2. 空值安全(Null Safety)

List.of("A", null); // 立即拋出NullPointerException
Set.of(null);       // 同上
Map.of("key", null);// 值也不能為null

設計哲學:在集合創建時嚴格拒絕null,避免后續NPE隱患。

3. 元素唯一性保證(針對Set/Map)

Set.of(1, 1); // 直接拋出IllegalArgumentException
Map.of("a", 1, "a", 2); // 鍵重復,拋出異常

4. 性能優化

JVM針對工廠方法返回的集合做了深度優化:

  • 內存占用:比new ArrayList節省約30%內存
  • 迭代速度:比傳統集合快2-3倍(得益于緊湊存儲)
  • 哈希計算Set.of/Map.of在創建時預計算哈希值

三、與傳統方式對比

1. 創建不可變List

Java 8方式

List<String> list = Collections.unmodifiableList(new ArrayList<>(Arrays.asList("A", "B"))
);
// 需要兩層包裝,內存開銷大

Java 9方式

List<String> list = List.of("A", "B");
// 直接返回優化后的不可變實例

2. 創建不可變Set

傳統方式

Set<Integer> set = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(1, 2, 3))
);
// 無法保證初始化時的元素唯一性

新方式

Set<Integer> set = Set.of(1, 2, 3);
// 自動檢查元素唯一性,發現重復立即報錯

3. 創建不可變Map

傳統方式

Map<String, Integer> tempMap = new HashMap<>();
tempMap.put("a", 1);
tempMap.put("b", 2);
Map<String, Integer> map = Collections.unmodifiableMap(tempMap);
// 需要中間變量,存在競態條件風險

新方式

Map<String, Integer> map = Map.of("a", 1, "b", 2);
// 線程安全,無中間狀態

四、使用注意事項

1. 元素限制

  • 數量限制Map.of最多接受10個鍵值對(超過需用Map.ofEntries
  • 類型限制:不支持基本類型(需用包裝類)
    List.of(1, 2, 3);      // 正確:自動裝箱
    List.of(new int[]{1}); // 錯誤:實際類型為List<int[]>
    

2. 防御性編程

// 接收外部集合時創建防御副本
void process(List<String> input) {List<String> safeList = List.copyOf(input); // Java 10+// 或 List<String> safeList = List.of(input.toArray());
}

3. 與Stream API結合

// 過濾后生成不可變集合
List<String> filtered = Stream.of("A", "B", "C").filter(s -> s.length() > 1).collect(Collectors.toUnmodifiableList());

五、最佳實踐場景

1. 配置參數存儲

private static final Set<String> VALID_STATUSES = Set.of("NEW", "PROCESSING", "COMPLETED");

2. 測試數據構造

@Test
void testSort() {List<Integer> numbers = List.of(3, 1, 4);Collections.sort(numbers); // 立即拋出UnsupportedOperationException
}

3. 返回值保護

public List<Employee> getEmployees() {return List.copyOf(internalList); // 返回不可變副本
}

六、常見問題解答

Q1:為什么需要新的工廠方法?

  • 類型安全:編譯時即可發現修改操作
  • 性能優勢:專用實現比通用集合更高效
  • 語義清晰:明確表達不可變意圖

Q2:如何創建空集合?

List<String> emptyList = List.of(); // 空集合單例
Set<Integer> emptySet = Set.of();
Map<String, String> emptyMap = Map.of();

Q3:與Arrays.asList的區別?

特性List.ofArrays.asList
可變性完全不可變半可變(可set不可add)
空值支持? 禁止null? 允許null
與原數組關聯? 獨立存儲? 共享底層數組
內存占用優化后的緊湊結構包裝器+數組引用

七、總結

使用新工廠方法的三大理由

  1. 🛡? 安全性:杜絕意外修改,強化空值約束
  2. 🚀 性能:專為不可變場景優化,內存效率更高
  3. ? 簡潔性:一行代碼表達創建不可變集合的意圖

適用原則

  • 優先用于靜態配置數據
  • 推薦作為方法返回值防止外部修改
  • 適合存儲需要確保完整性的業務數據

遷移建議

  • 逐步替換項目中Collections.unmodifiableXXX的用法
  • 在單元測試中優先采用新語法
  • 注意檢查歷史代碼中的null值使用

Java 9的集合工廠方法不僅是語法糖,更是工程實踐的重要進步。合理運用這些特性,可以讓代碼更健壯、更高效,同時降低維護成本。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/899315.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/899315.shtml
英文地址,請注明出處:http://en.pswp.cn/news/899315.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

網絡通信微服務

網絡通信 VPN 服務器分配內網 IP&#xff0c;加密所有流量,以使用外網訪問內網資源 使用了VPN只是第一關&#xff0c;只進入了人家的大廳&#xff0c;只可以訪問公共服務&#xff08;像是只可以在人間公司的大廳里溜達&#xff09;&#xff0c;若想要訪問人家提供的高級服務&a…

arm之s3c2440的I2C的用法

基礎概念 IC&#xff08;Inter-Integrated Circuit&#xff09;又稱I2C&#xff0c;是是IICBus簡稱&#xff0c;所以中文應該叫集成電路總線。 IIC的總線的使用場景&#xff0c;所有掛載在IIC總線上的設備都有兩根信號線&#xff0c;一根是數據線SDA&#xff0c;另一 根是時鐘…

算法 | 蜣螂優化算法原理,引言,公式,算法改進綜述,應用場景及matlab完整代碼

蜣螂優化算法(Dung Beetle Optimizer, DBO)詳解 1. 算法原理 蜣螂優化算法(DBO)是一種基于自然界蜣螂行為的元啟發式優化算法,靈感來源于蜣螂的滾球、繁殖、覓食和偷竊行為。其核心思想是通過模擬蜣螂在復雜環境中的協作與競爭機制,解決全局優化問題。關鍵行為模擬: 滾球…

uniapp開發實戰自定義組件形式實現自定義海報功能

在 UniApp 中實現自定義海報功能,可以通過 Canvas 來繪制海報。Canvas 提供了豐富的繪圖 API,可以精確控制文字、圖片和二維碼的位置。下面是一個完整的示例,展示如何創建一個自定義海報組件。 項目結構 假設你的項目結構如下: project-root/ ├── pages/ │ └──…

dockerfile構建鏡像方式

在 Docker 中&#xff0c;可使用 docker build 命令依據 Dockerfile 構建鏡像。下面為你詳細介紹構建鏡像的具體方式。 基本構建命令 若要構建鏡像&#xff0c;需在包含 Dockerfile 的目錄下執行 docker build 命令。基本語法如下&#xff1a; bash docker build -t <鏡像…

STM32F103_LL庫+寄存器學習筆記10 - DMA傳輸過半+DMA傳輸完成中斷實現DMA串口接收“雙緩沖“

導言 《[[STM32F103_LL庫寄存器學習筆記09 - DMA串口接收與DMA串口發送&#xff0c;串口接收空閑中斷]]》上一章節完成DMA發送與接收。此時&#xff0c;有一個致命的問題可能會導致數據包丟失。原因是USART1接收只開啟了接收空閑中斷(IDLE)&#xff0c;DMA在連續模式下&#xf…

李宏毅機器學習筆記06 | 魚和熊掌可以兼得的機器學習 - 內容接寶可夢

本章提要 深度學習可以在較少參數量的情況下得到比較低的loss&#xff1a; h a l l a r g min ? h ∈ H L ( h , D a l l ) h^{all}arg \min_{h \in H}L(h,D_{all}) hallargminh∈H?L(h,Dall?) 引入 如何權衡模型的復雜程度 Tradeoff of Model Complexity 理論上&#…

java八股文之JVM

1.什么是程序計數器 程序計數器是 JVM 管理線程執行的“定位器”&#xff0c;記錄每個線程當前執行的指令位置&#xff0c;確保程序流程的連續性和線程切換的準確性。線程私有的&#xff0c;每個線程一份&#xff0c;內部保存的字節碼的行號。用于記錄正在執行的字節碼指令的地…

Android設計模式之觀察者模式

一、定義&#xff1a;定義對象間一種一對多的依賴關系&#xff0c;使得每當一個對象改變狀態&#xff0c;則所有依賴于它的對象都會得到通知并被自動更新。 二、核心角色&#xff1a; Subject&#xff1a;抽象主題被觀察的角色&#xff0c;管理觀察者集合&#xff0c;提供注冊…

海康gdb流程

gdb相關 在initrun.sh文件里加入&#xff0c;注意需要在hikauto起來之前 # 設置core dump大小 ulimit -c unlimited if [ $? -eq 0 ];then echo "core dump size set success" else echo -e "\33[31m core dump size set fail\33[0m" fi echo …

springBoot統一響應類型3.3版本

前言&#xff1a; 通過實踐而發現真理&#xff0c;又通過實踐而證實真理和發展真理。從感性認識而能動地發展到理性認識&#xff0c;又從理性認識而能動地指導革命實踐&#xff0c;改造主觀世界和客觀世界。實踐、認識、再實踐、再認識&#xff0c;這種形式&#xff0c;循環往…

【空間變換】歐拉角與四元數

核心 歐拉角描述的是一種變換&#xff0c;只關注變換后的結果&#xff0c;不關注變換過程中的運動 而四元數不僅良好地表示了一種變換&#xff0c;也很好地表示了一種運動過程&#xff0c;又避免了萬向節死鎖Gimbal Lock變換順序&#xff0c;是歐拉角變換的一部分&#xff0c;…

基于Linux下的MyBash命令解釋器

項目介紹&#xff1a;?個?C語?實現的簡單shell&#xff0c;可以接受??輸?的命令并執?操作&#xff0c;?持多管道和重 定向。 mybash---打造自己的命令解釋器 目前我們Linux的系統默認的命令解釋器是bash; 命令解釋器&#xff08;也稱為命令行解釋器或shell&#xff0…

Linux常見使用場景

一、文件查看與內容操作 ?1. cat ?作用&#xff1a;查看文件內容&#xff08;一次性輸出全部內容&#xff09;。?常用選項&#xff1a; -n&#xff1a;顯示行號。-b&#xff1a;僅對非空行顯示行號。 ?示例&#xff1a; cat file.txt # 查看文件內容 cat -n fil…

Ingredient-oriented Multi-Degradation Learning for Image Restoration論文閱讀

摘要&#xff1a;重點在于關聯多個任務本質的聯系。 不同恢復任務的關聯性很重要。 揭示退化現象的內在機理聯系很有意義。 多合一的方法能在單一模型中處理多種退化問題&#xff0c;可擴展性較差。 成分導向范式挖掘不同圖像退化現象背后的物理規律或特征模式。 成分導向退化重…

禪道后臺命令執行漏洞

漏洞簡介 禪道是第一款國產的開源項目管理軟件。它集產品管理、項目管理、質量管理、文檔管理、 組織管理和事務管理于一體&#xff0c;是一款專業的研發項目管理軟件&#xff0c;完整地覆蓋了項目管理的核心流程。 禪道管理思想注重實效&#xff0c;功能完備豐富&#xff0c;…

密碼學——知識問答

目錄 1、闡述公開密鑰算法的定義&#xff0c;結合RSA算法說明公鑰密碼的基本要求。 說明公鑰與私鑰兩種密碼學并舉例與其應用 1. 公鑰密碼學&#xff08;非對稱加密&#xff09;&#xff1a; 2. 私鑰密碼學&#xff08;對稱加密&#xff09;&#xff1a; 對比公鑰與私鑰密碼…

PDF多表格結構識別與跨表語義對齊:基于對抗遷移的魯棒相似度度量模型

文章目錄 一. 項目結構二.流程分析2.1 批處理器核心代碼解析 三. 跨頁表格相似度匹配原理3.1 表頭內容相似度-特征向量歸一化3.2 表頭內容相似度-余弦相似度3.3 定時緩存清理 ocr掃描有其局限性。對于pdf文本類型這種pdfbox&#xff0c;aspose-pdf&#xff0c;spire直接提取文本…

es 3期 第27節-運用Script腳本實現復雜需求

#### 1.Elasticsearch是數據庫&#xff0c;不是普通的Java應用程序&#xff0c;傳統數據庫需要的硬件資源同樣需要&#xff0c;提升性能最有效的就是升級硬件。 #### 2.Elasticsearch是文檔型數據庫&#xff0c;不是關系型數據庫&#xff0c;不具備嚴格的ACID事務特性&#xff…

23、web前端開發之html5(四)

十二. HTML5實踐示例 前面我們詳細講解了HTML5的特點&#xff0c;包括語義化標簽、增強的表單功能、多媒體元素&#xff08;如<video>和<audio>&#xff09;、Canvas繪圖、SVG集成以及離線存儲等。以下是一些詳細的HTML5實踐示例&#xff0c;展示如何使用HTML5的新…