Java Collection API加强功能系列之二 List.of、Set.of、Map.of

[复制链接]
发表于 2025-10-9 21:32:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
Java 9聚集工厂方法:用List.of、Set.of、Map.of创建安全不可变聚集

Java 9引入了革命性的聚集工厂方法List.of、Set.of和Map.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 伪不可变)

传统方式的标题:
  1. // Java 8的"不可变"集合
  2. List<String> oldList = Collections.unmodifiableList(
  3.     new ArrayList<>(Arrays.asList("A", "B"))
  4. );
  5. oldList.add("C"); // 运行时抛出UnsupportedOperationException
复制代码
新方式:
  1. List<String> newList = List.of("A", "B");
  2. newList.add("C"); // 编译期即可通过IDE提示发现问题
复制代码
特性新工厂方法Collections.unmodifiableList编译期范例查抄✅ 直接拒绝修改操纵❌ 运行时非常防御原聚集修改✅ 完全独立❌ 包装聚集仍受原聚集影响2. 空值安全(Null Safety)
  1. List.of("A", null); // 立即抛出NullPointerException
  2. Set.of(null);       // 同上
  3. Map.of("key", null);// 值也不能为null
复制代码
计划哲学:在聚集创建时严酷拒绝null,制止后续NPE隐患。
3. 元素唯一性包管(针对Set/Map)
  1. Set.of(1, 1); // 直接抛出IllegalArgumentException
  2. Map.of("a", 1, "a", 2); // 键重复,抛出异常
复制代码
4. 性能优化

JVM针对工厂方法返回的聚集做了深度优化:

  • 内存占用:比new ArrayList节流约30%内存
  • 迭代速率:比传统聚集快2-3倍(得益于紧凑存储)
  • 哈希盘算:Set.of/Map.of在创建时预盘算哈希值

三、与传统方式对比

1. 创建不可变List

Java 8方式:
  1. List<String> list = Collections.unmodifiableList(
  2.     new ArrayList<>(Arrays.asList("A", "B"))
  3. );
  4. // 需要两层包装,内存开销大
复制代码
Java 9方式:
  1. List<String> list = List.of("A", "B");
  2. // 直接返回优化后的不可变实例
复制代码
2. 创建不可变Set

传统方式:
  1. Set<Integer> set = Collections.unmodifiableSet(
  2.     new HashSet<>(Arrays.asList(1, 2, 3))
  3. );
  4. // 无法保证初始化时的元素唯一性
复制代码
新方式:
  1. Set<Integer> set = Set.of(1, 2, 3);
  2. // 自动检查元素唯一性,发现重复立即报错
复制代码
3. 创建不可变Map

传统方式:
  1. Map<String, Integer> tempMap = new HashMap<>();
  2. tempMap.put("a", 1);
  3. tempMap.put("b", 2);
  4. Map<String, Integer> map = Collections.unmodifiableMap(tempMap);
  5. // 需要中间变量,存在竞态条件风险
复制代码
新方式:
  1. Map<String, Integer> map = Map.of("a", 1, "b", 2);
  2. // 线程安全,无中间状态
复制代码

四、利用注意事项

1. 元素限定


  • 数目限定:Map.of最多担当10个键值对(凌驾需用Map.ofEntries)
  • 范例限定:不支持根本范例(需用包装类)
    1. List.of(1, 2, 3);      // 正确:自动装箱
    2. List.of(new int[]{1}); // 错误:实际类型为List<int[]>
    复制代码
2. 防御性编程
  1. // 接收外部集合时创建防御副本
  2. void process(List<String> input) {
  3.     List<String> safeList = List.copyOf(input); // Java 10+
  4.     // 或 List<String> safeList = List.of(input.toArray());
  5. }
复制代码
3. 与Stream API团结
  1. // 过滤后生成不可变集合
  2. List<String> filtered = Stream.of("A", "B", "C")
  3.                              .filter(s -> s.length() > 1)
  4.                              .collect(Collectors.toUnmodifiableList());
复制代码

五、最佳实践场景

1. 设置参数存储
  1. private static final Set<String> VALID_STATUSES =
  2.     Set.of("NEW", "PROCESSING", "COMPLETED");
复制代码
2. 测试数据构造
  1. @Test
  2. void testSort() {
  3.     List<Integer> numbers = List.of(3, 1, 4);
  4.     Collections.sort(numbers); // 立即抛出UnsupportedOperationException
  5. }
复制代码
3. 返回值掩护
  1. public List<Employee> getEmployees() {
  2.     return List.copyOf(internalList); // 返回不可变副本
  3. }
复制代码

六、常见标题解答

Q1:为什么须要新的工厂方法?


  • 范例安全:编译时即可发现修改操纵
  • 性能上风:专用实现比通用聚集更高效
  • 语义清晰:明确表达不可变意图
Q2:怎样创建空聚集?
  1. List<String> emptyList = List.of(); // 空集合单例
  2. Set<Integer> emptySet = Set.of();
  3. Map<String, String> emptyMap = Map.of();
复制代码
Q3:与Arrays.asList的区别?

特性List.ofArrays.asList可变性完全不可变半可变(可set不可add)空值支持❌ 克制null✅ 答应null与原数组关联❌ 独立存储✅ 共享底层数组内存占用优化后的紧凑布局包装器+数组引用
七、总结

利用新工厂方法的三大来由:

  • 🛡️ 安全性:杜绝不测修改,强化空值束缚
  • 🚀 性能:专为不可变场景优化,内存服从更高
  • ✨ 简便性:一行代码表达创建不可变聚集的意图
实用原则:

  • 优先用于静态设置数据
  • 保举作为方法返回值防止外部修改
  • 得当存储须要确保完备性的业务数据
迁移发起:

  • 渐渐更换项目中Collections.unmodifiableXXX的用法
  • 在单位测试中优先接纳新语法
  • 注意查抄汗青代码中的null值利用
Java 9的聚集工厂方法不光是语法糖,更是工程实践的紧张进步。公道运用这些特性,可以让代码更坚固、更高效,同时低沉维护本钱。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表