当前位置: 首页 > news >正文

Java进阶学习之不可变集合

        在 Java 编程中,不可变集合是一种非常重要的概念,它提供了诸多优势,如线程安全、可靠性和性能优化等。下面将从多个方面详细介绍 Java 中的不可变集合。

一、不可变集合的特点

        不可变集合是指创建后其内容不能被修改的集合。一旦创建,就不能添加、删除或修改集合中的元素。这种特性使得不可变集合在多线程环境下是线程安全的,因为没有并发修改的风险。

  1. 线程安全:由于不可修改,天然线程安全,无需额外同步。
  2. 内存效率:多个引用可以共享同一个不可变集合实例。
  3. 防御性编程:防止意外修改,确保数据完整性。
  4. 作为常量:适合作为API返回值或配置常量。

不可变集合的局限性

  • 创建后无法修改:如果需要动态修改集合内容,不可变集合就不适用,需要使用可变集合。
  • 创建成本:在某些情况下,创建不可变集合可能需要额外的资源和时间,特别是当集合元素较多时。

二、不可变集合的创建方法对比

方法版本要求特点
List.of()Java 9+简洁,支持可变参数,快速创建不可变List
Set.of()Java 9+简洁,支持可变参数,快速创建不可变Set
Map.of()/Map.ofEntries()Java 9+简洁,支持键值对创建不可变Map
Collections.unmodifiableXXX()Java 1.2+创建视图,依赖原始集合,不推荐用于创建真正的不可变集合
Guava的ImmutableList任意需要额外依赖,提供更多不可变集合实现

1.Java 8 及以前的实现方式

在 Java 8 及以前,可以使用 Collections 工具类的静态方法来创建不可变集合。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class ImmutableCollectionBeforeJava9 {public static void main(String[] args) {// 创建一个普通的可变列表List<String> mutableList = new ArrayList<>();mutableList.add("apple");mutableList.add("banana");mutableList.add("cherry");// 使用 Collections.unmodifiableList() 方法创建不可变列表List<String> immutableList = Collections.unmodifiableList(mutableList);try {// 尝试修改不可变列表,会抛出 UnsupportedOperationExceptionimmutableList.add("date");} catch (UnsupportedOperationException e) {System.out.println("不能修改不可变列表:" + e.getMessage());}// 注意:如果修改原始的可变列表,不可变列表也会受到影响mutableList.add("elderberry");System.out.println("不可变列表:" + immutableList);}
}

2.Java 9 及以后的实现方式

Java 9 引入了一系列工厂方法来创建不可变集合,使用起来更加简洁。

import java.util.List;
import java.util.Map;
import java.util.Set;public class ImmutableCollectionJava9 {public static void main(String[] args) {// 创建不可变列表List<String> immutableList = List.of("apple", "banana", "cherry");// 创建不可变集合Set<String> immutableSet = Set.of("apple", "banana", "cherry");// 创建不可变映射Map<String, Integer> immutableMap = Map.of("apple", 1, "banana", 2, "cherry", 3);try {// 尝试修改不可变列表,会抛出 UnsupportedOperationExceptionimmutableList.add("date");} catch (UnsupportedOperationException e) {System.out.println("不能修改不可变列表:" + e.getMessage());}try {// 尝试修改不可变集合,会抛出 UnsupportedOperationExceptionimmutableSet.add("date");} catch (UnsupportedOperationException e) {System.out.println("不能修改不可变集合:" + e.getMessage());}try {// 尝试修改不可变映射,会抛出 UnsupportedOperationExceptionimmutableMap.put("date", 4);} catch (UnsupportedOperationException e) {System.out.println("不能修改不可变映射:" + e.getMessage());}}
}

    三. 与可变集合的转换

            如果需要将不可变集合转换为可变集合,可以通过创建一个新的可变集合并将不可变集合的元素复制到其中。

    import java.util.ArrayList;
    import java.util.List;public class ConvertImmutableToMutable {public static void main(String[] args) {// 创建不可变列表List<String> immutableList = List.of("apple", "banana", "cherry");// 将不可变列表转换为可变列表List<String> mutableList = new ArrayList<>(immutableList);// 可以对可变列表进行修改mutableList.add("date");System.out.println("可变列表:" + mutableList);}
    }

    五、使用场景

    1. 配置信息:程序启动时加载的配置
    2. 常量集合:如国家/地区代码等
    3. 多线程共享数据:避免并发修改问题
    4. API返回值:防止调用方修改内部数据
    5. 函数参数:确保函数不会修改输入集合

    六、注意事项

    1. Collections.unmodifiableXXX方法返回的是视图,原始集合的修改会反映到视图
    2. Java 9+的of()方法创建的集合是真正不可变的
    3. 尝试修改不可变集合会抛出UnsupportedOperationException
    4. 不可变集合可以包含null元素(Java 9+的of()方法不允许)
    List<String> list = List.of("a", "b", "c");
    list.add("d"); // 抛出UnsupportedOperationExceptionSet<Integer> set = Set.of(1, 2, 3);
    set.remove(1); // 抛出UnsupportedOperationExceptionMap<String, Integer> map = Map.of("one", 1);
    map.put("two", 2); // 抛出UnsupportedOperationException

    掌握不可变集合的使用,可以显著提高Java程序的健壮性和安全性,特别是在多线程环境下。

    http://www.lryc.cn/news/618622.html

    相关文章:

  • 数据分析学习总结之实例练习(双十一淘宝美妆)
  • 非凸科技受邀参加Community Over Code Asia 2025 Rust分论坛
  • C#教程之NPOI读写excel文件XLS,XLSX格式
  • FPGA自学——FIFO缓存器
  • VisionPro——1.VP与C#联合
  • 初识数据结构——优先级队列(堆!堆!堆!)
  • 模板打印技术——Office XLS 打印模板:为政务土地确权定制的纸张替换利器—仙盟创梦IDE
  • LE AUDIO---Volume Control Service
  • Kimi K2 架构深度解析:万亿MoE模型的效率革命与智能体突破
  • 用STM32单片机控制支持正反转的电调
  • 1、JVM内存模型剖析及优化
  • Altium Designer 22使用笔记(6)---板框导入、自绘板框、原点设置
  • 荣耀手机无法连接win11电脑,错误消息:“无法在此设备上加载驱动程序 (hn_usbccgpfilter.sys)。”解决方案
  • 【Linux】Ext系列文件系统
  • 数据结构:后缀表达式:结合性 (Associativity) 与一元运算符 (Unary Operators)
  • 现代化水库运行管理矩阵建设的要点
  • AI Agent——基于 LangGraph 的多智能体任务路由与执行系统实战
  • 【实时Linux实战系列】实时能耗监测与优化技术
  • 《吃透 C++ 类和对象(上):封装、实例化与 this 指针详解》
  • Python训练营打卡Day30-文件的规范拆分和写法
  • 543.二叉树的直径
  • 【前端:Html】--2.进阶:表单
  • 数字孪生重构园区管理效率:技术落地与产业升级的三重跃迁
  • JVM学习笔记-----图解方法执行流程
  • Nginx 启用 HTTPS:阿里云免费 SSL 证书详细图文教程(新手0.5小时可完成)
  • openssl中,公钥和私钥的区别和作用?
  • API 接口接入开发全演示:淘宝商品数据实时抓取
  • 代码随想录刷题Day29
  • 基于51单片机220V交流电流检测系统过流阈值报警设计
  • 通信接口与通信约规