arrays.aslist返回的列表遍历极快但修改受限:读取为o(1)零拷贝,适合只读场景;add/remove等结构性操作一律抛unsupportedoperationexception;基本类型数组会语义错误,需用包装类或stream转换;需可变集合时应避免套娃,优先用collections.addall或stream.collect。

Arrays.asList 返回的列表性能表现两极分化:遍历极快,修改受限且危险。
遍历操作:O(1) 读取,零拷贝开销
它不复制数组,而是直接持有一个对原数组的引用。所以 get(i)、forEach、for-each 循环等读取行为,本质就是数组索引访问,没有额外对象创建或内存拷贝,比新建 ArrayList 遍历还轻量。
- 适合只读场景:参数校验、批量查询、模板渲染等无需增删的流程
- 多线程下需注意:get 是安全的,但若其他线程同时 set 修改原数组,结果不可预测
- 避免在高频循环中反复调用 Arrays.asList():虽然单次转换快,但频繁生成视图对象会增加 GC 压力
结构性修改:一律抛异常,不是慢,是根本不可行
add、remove、clear、addAll 等方法全部抛 UnsupportedOperationException——这不是性能问题,而是设计限制。底层数组长度固定,内部类 Arrays$ArrayList 没有重写这些方法,直接继承 AbstractList 的默认实现(即抛异常)。
- 别在 try-catch 里硬试 add:这是逻辑错误,不是容错策略
- set(i, x) 和 get(i) 可以用,但会同步改写原数组:若原数组后续还会被复用,这会造成隐蔽副作用
- 误以为“转成 List 就能用集合工具”是常见陷阱,尤其在 Stream.collect 或 Collections.frequency 等上下文中
基本类型数组:不是性能差,是语义错
传 int[]、long[] 等进去,得到的不是装箱后的 List
- 正确做法只有两个:用 Integer[] 等包装类型数组,或走 Stream:Arrays.stream(arr).boxed().collect(Collectors.toList())
- 后者虽有 O(n) 时间和装箱开销,但语义正确;前者需注意泛型擦除与初始化成本
- 大规模 int[] 场景,优先考虑 IntArrayList(Eclipse Collections)或直接用数组索引,绕过集合抽象
需要可变集合时:别套娃,一步到位
写 new ArrayList(Arrays.asList(arr)) 看似自然,实则先建视图、再遍历复制,做了两次数组扫描。更优路径是:
- 字符串/包装类数组:Collections.addAll(new ArrayList(arr.length), arr)
- Java 8+ 通用方式:Arrays.stream(arr).collect(Collectors.toCollection(ArrayList::new))
- 明确容量且元素不多:new ArrayList(Arrays.asList(arr)) 仍可接受,但需意识到它不是“最简路径”











