java中arraylist初始化需避免arrays.aslist()返回的不可变列表,应包装为new arraylist(arrays.aslist());java 9+推荐list.of()创建不可变集合;hashmap应预估容量避免频繁扩容。

Java中ArrayList初始化时用Arrays.asList()的坑
直接用 Arrays.asList("a", "b") 返回的不是真正的 ArrayList,而是 Arrays 的静态内部类,它不支持 add()、remove() 等修改操作,调用会抛 UnsupportedOperationException。
- 正确做法:包装一层新
ArrayList——new ArrayList(Arrays.asList("a", "b")) - 适用场景:初始化已知元素且后续需增删的列表
- 注意:原始数组和返回的 list 是“共享”底层数据的(对基本类型数组无效,但对象数组会反映引用变化)
Java 9+ 推荐用List.of()创建不可变集合
List.of()、Set.of()、Map.of() 是 Java 9 引入的工厂方法,语法简洁、线程安全、内存高效,但返回的是不可变集合。
- 写法示例:
List<string> list = List.of("x", "y", "z");</string> - 不能调用
add()、clear(),否则抛UnsupportedOperationException - 空值限制:所有参数不能为
null,否则抛NullPointerException - 适合场景:配置项、枚举常量、测试数据等只读用途
使用匿名内部类 + 实例初始化块模拟“双大括号初始化”
像 new ArrayList<string>() {{ add("a"); add("b"); }}</string> 这种写法虽短,但有严重隐患:
- 每次都会创建一个匿名子类,导致类加载器泄漏(尤其在频繁创建、长期运行的环境中)
- 序列化失败:匿名类默认持有外部类引用,若外部类不可序列化则报错
- 调试困难:堆栈里出现类似
MyClass$1的无意义类名 - 替代方案:优先用
Arrays.asList()包装,或 Java 10+ 的var list = new ArrayList(List.of("a", "b"));
HashMap初始化时指定初始容量避免扩容抖动
默认构造的 HashMap 初始容量是 16,负载因子 0.75,即插入第 13 个元素就触发 resize。高频写入场景下,反复扩容影响性能。
立即学习“Java免费学习笔记(深入)”;
- 预估数量后设置合理初始容量:比如要存 100 个键值对,建议
new HashMap(128)(向上取最接近的 2 的幂) - 更稳妥写法:
new HashMap(Math.max(16, (int) Math.ceil(expectedSize / 0.75))) - 注意:传入的数字会被自动调整为大于等于它的最小 2 的幂(如传 100 → 实际容量 128)
- ConcurrentHashMap 不同:它的构造参数是「并发级别」,不是容量,Java 8+ 已忽略该参数,推荐直接用无参构造
List.of() 能当普通 ArrayList 用,结果在第一次 add() 就崩掉;还有就是 HashMap 容量拍脑袋设成 10 或 100,没考虑扩容机制,压测时 CPU 突然拉高。









