Collection接口与原生数组操作对象完全不同:Collections只能操作Collection实现类,Arrays专为原生数组设计;排序行为、类型支持、线程安全及不可变包装等方面存在显著差异。

操作对象完全不同:Collection接口 vs 原生数组
Collections 只能操作 Collection 接口的实现类(如 ArrayList、LinkedList、HashSet),不能对普通数组(如 int[]、String[])直接调用;Arrays 则专为原生数组设计,所有方法都要求传入 [] 类型参数——传错类型编译直接报错。
- 传
ArrayList给Arrays.sort()?编译失败:方法不接受List - 传
String[]给Collections.sort()?编译失败:方法只认List - 想对数组排序但误用
Collections.sort(),常见错误是先调Arrays.asList(arr)转成List,但要注意:该List是固定大小的视图,底层仍绑定原数组,add()或remove()会抛UnsupportedOperationException
排序行为差异大:稳定性和基本类型支持
Collections.sort() 本质是把 List 转成数组,调 Arrays.sort(Object[]),再复制回 List;而 Arrays.sort() 对不同数组类型走不同算法:对象数组用稳定的 TimSort,基本类型数组(如 int[])用不稳定的双轴快排。
- 需要稳定排序(相等元素顺序不变)?用
Collections.sort(list)或Arrays.sort(objArray),别用Arrays.sort(int[]) - 处理
int[]又要稳定?转成Integer[]再排:Arrays.sort(IntStream.of(nums).boxed().toArray(Integer[]::new)) -
Collections.sort()不支持基本类型集合(Java 没有int List),必须用包装类
集合与数组互转:asList() 和 toArray() 的坑最多
Arrays.asList() 返回的是 Arrays$ArrayList(非 java.util.ArrayList),它不支持结构性修改;Collection.toArray() 若不传参,返回的是 Object[],强转具体类型数组会抛 ClassCastException。
- 错误写法:
String[] arr = Arrays.asList("a","b").toArray();→ 编译不过,因为toArray()返回Object[] - 正确写法:
String[] arr = Arrays.asList("a","b").toArray(new String[0]); - 更安全写法:
String[] arr = list.toArray(String[]::new);(Java 11+) -
Arrays.asList(new int[]{1,2,3})结果是含一个int[]元素的List,不是三个Integer!基本类型数组传进去会被当单个对象
线程安全和不可变包装:Collections 提供而 Arrays 没有
Collections 提供 synchronizedXxx() 和 unmodifiableXxx() 系列方法,能快速获得线程安全或只读视图;Arrays 完全不涉及这类抽象,它只管数据搬运和计算。
立即学习“Java免费学习笔记(深入)”;
- 让
ArrayList线程安全:Collections.synchronizedList(new ArrayList())(注意:迭代时仍需手动同步) - 返回不可修改集合:
Collections.unmodifiableList(list),后续任何修改操作都抛UnsupportedOperationException -
Arrays没有类似方法——它连“集合”都不是,自然不提供集合语义的保护机制
真正容易被忽略的点是:Arrays.asList() 和 Collections.singletonList() 表面都返回 List,但前者可变(支持 set())、后者完全不可变;还有,Collections.emptyXXX() 返回的是单例实例,而 new ArrayList() 每次新建对象——在高频创建场景下,这点内存和 GC 差异会实实在在体现出来。









