一、Collections 工具类

专门操作 Collection 体系(List、Set)和 Map 的工具类,核心功能涵盖排序、查找、填充、同步化、不可变封装等。

1. 核心功能分类 & 常用方法

功能分类方法签名(核心)说明
排序(List)sort(List<T> list)自然排序:要求元素实现 Comparable 接口,升序排列
sort(List<T> list, Comparator<? super T> c)定制排序:通过 Comparator 自定义排序规则
reverse(List<?> list)反转列表元素顺序
shuffle(List<?> list)随机打乱列表(洗牌),常用于随机排序
swap(List<?> list, int i, int j)交换列表中指定索引的两个元素
rotate(List<?> list, int distance)旋转列表:distance 正数右移,负数左移(如 distance=1,最后一个元素移到首位)
查找/替换binarySearch(List<T> list, T key)二分查找:前提是列表已排序(自然排序),找到返回索引,否则返回 -(插入点)-1
binarySearch(List<T> list, T key, Comparator<? super T> c)带比较器的二分查找
max(Collection<T> coll) / min(Collection<T> coll)找集合的最大/最小值(自然排序)
max(Collection<T> coll, Comparator<? super T> c)定制规则找最大/最小值
fill(List<? super T> list, T obj)用指定元素填充整个列表(覆盖所有元素)
replaceAll(List<T> list, T oldVal, T newVal)替换列表中所有旧元素为新元素
frequency(Collection<?> c, Object o)统计元素在集合中出现的次数
同步化包装synchronizedList(List<T> list)返回线程安全的 List(底层加锁,性能较低)
synchronizedSet(Set<T> s) / synchronizedMap(Map<K,V> m)返回线程安全的 Set/Map
不可变封装emptyList() / emptySet() / emptyMap()返回空的不可变集合(复用单例,节省内存)
singletonList(T o) / singletonSet(T o) / singletonMap(K k, V v)返回包含单个元素的不可变集合
unmodifiableList(List<? extends T> list)将现有集合包装为不可变集合(修改会抛 UnsupportedOperationException
其他工具addAll(Collection<? super T> c, T... elements)批量添加元素到集合
disjoint(Collection<?> c1, Collection<?> c2)判断两个集合是否无交集(无则返回 true)
copy(List<? super T> dest, List<? extends T> src)复制 src 到 dest:要求 dest 容量 ≥ src 大小,否则抛 IndexOutOfBoundsException
nCopies(int n, T o)返回包含 n 个相同元素的不可变 List

2. 关键示例

(1)排序(自然 + 定制)
List<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 2));
// 自然排序(升序)
Collections.sort(list); // [1,2,3]
// 定制排序(降序)
Collections.sort(list, (a, b) -> b - a); // [3,2,1]
// 反转
Collections.reverse(list); // [1,2,3]
// 洗牌
Collections.shuffle(list);
(2)不可变集合
// 空不可变List
List<String> emptyList = Collections.emptyList();
// 单元素不可变List
List<String> singletonList = Collections.singletonList("test");
// 包装现有List为不可变
List<String> mutableList = new ArrayList<>();
mutableList.add("a");
List<String> unmodifiableList = Collections.unmodifiableList(mutableList);
// 不可变集合修改会抛异常
// unmodifiableList.add("b"); // UnsupportedOperationException
(3)同步化集合
// 线程安全的List
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
// 迭代时需手动加锁(否则可能抛ConcurrentModificationException)
synchronized (syncList) {
    for (String s : syncList) {
        System.out.println(s);
    }
}

3. 注意事项

  • 不可变集合的“假不可变”unmodifiableXXX 仅包装原集合,若原集合修改,包装后的不可变集合会同步变化(因为是引用传递)。
  • copy 方法的容量要求Collections.copy(dest, src) 要求 dest.size() ≥ src.size(),而非仅容量(需提前初始化 dest 大小)。
  • 同步化集合性能:底层通过 synchronized 加锁,性能低于 java.util.concurrent 包下的并发集合(如 CopyOnWriteArrayList)。

二、Arrays 工具类

专门操作数组(基本类型数组、对象数组)的工具类,核心功能涵盖排序、查找、填充、复制、数组转集合、比较/哈希等。

1. 核心功能分类 & 常用方法

功能分类方法签名(核心)说明
排序sort(int[] a) / sort(Object[] a)基本类型数组升序;对象数组要求元素实现 Comparable
sort(Object[] a, Comparator<? super T> c)对象数组定制排序(仅支持对象数组,不支持基本类型)
parallelSort(int[] a)并行排序:大数据量(百万级)更高效(Java 8+)
查找binarySearch(int[] a, int key) / binarySearch(Object[] a, Object key)二分查找:数组需先排序,找到返回索引,否则返回 -(插入点)-1
binarySearch(Object[] a, Object key, Comparator<? super T> c)带比较器的二分查找(仅对象数组)
填充fill(int[] a, int val) / fill(Object[] a, T val)填充整个数组
fill(int[] a, int fromIndex, int toIndex, int val)填充指定范围(左闭右开)
复制copyOf(int[] original, int newLength)复制数组:新长度,不足补默认值(基本类型 0,对象 null)
copyOfRange(int[] original, int from, int to)复制指定范围(左闭右开)
数组转集合asList(T... a)将数组转为 List(注意:返回的是 Arrays.ArrayList,非 java.util.ArrayList
比较/哈希equals(int[] a, int[] a2)比较两个数组是否相等(长度+对应元素)
deepEquals(Object[] a1, Object[] a2)深度比较:用于多维数组
toString(int[] a)返回数组的字符串表示(如 [1,2,3]
deepToString(Object[] a)多维数组的字符串表示
其他stream(int[] a)转为 Stream(Java 8+)
mismatch(int[] a, int[] a2)查找第一个不匹配的索引,无则返回 -1(Java 9+)

2. 关键示例

(1)排序 & 二分查找
int[] arr = {3, 1, 2};
// 排序
Arrays.sort(arr); // [1,2,3]
// 二分查找
int index = Arrays.binarySearch(arr, 2); // 返回1
int notFoundIndex = Arrays.binarySearch(arr, 4); // 返回-4(-(3)-1)

// 对象数组定制排序
String[] strArr = {"b", "a", "c"};
Arrays.sort(strArr, (s1, s2) -> s2.compareTo(s1)); // [c,b,a]
(2)数组复制
int[] original = {1,2,3};
// 复制为新长度(不足补0)
int[] copy1 = Arrays.copyOf(original, 5); // [1,2,3,0,0]
// 复制指定范围
int[] copy2 = Arrays.copyOfRange(original, 0, 2); // [1,2]

// 底层依赖的System.arraycopy(更高效)
int[] dest = new int[3];
System.arraycopy(original, 0, dest, 0, original.length);
(3)数组转集合(重点避坑)
// 正确:包装类数组转List
Integer[] intArr = {1,2,3};
List<Integer> list1 = Arrays.asList(intArr);

// 错误:基本类型数组转List(会被当成单个元素)
int[] primitiveArr = {1,2,3};
List<int[]> list2 = Arrays.asList(primitiveArr); // 类型是List<int[]>,而非List<Integer>

// 注意:Arrays.asList返回的List不可增删(固定大小)
// list1.add(4); // UnsupportedOperationException
// 若需可变List,需二次包装
List<Integer> mutableList = new ArrayList<>(Arrays.asList(intArr));
mutableList.add(4); // 正常
(4)多维数组比较 & 字符串表示
// 多维数组
int[][] arr1 = {{1,2}, {3,4}};
int[][] arr2 = {{1,2}, {3,4}};
int[][] arr3 = {{1,2}, {3,5}};

// 深度比较
System.out.println(Arrays.deepEquals(arr1, arr2)); // true
System.out.println(Arrays.deepEquals(arr1, arr3)); // false

// 深度字符串表示
System.out.println(Arrays.deepToString(arr1)); // [[1,2],[3,4]]

3. 注意事项

  • Arrays.asList 坑点
    • 基本类型数组转换会被视为单个元素(需用包装类数组);
    • 返回的 Arrays.ArrayList 是静态内部类,无 add/remove 方法(仅实现 set),修改会抛异常;
  • 二分查找前提:必须先排序,否则结果无意义;
  • parallelSort 适用场景:仅大数据量(百万级以上)有性能优势,小数据量反而因线程开销更慢。

三、Collections & Arrays 对比

维度CollectionsArrays
操作对象List、Set、Map(集合)基本类型数组、对象数组
核心功能排序(仅List)、查找、填充、同步化、不可变封装排序(所有数组)、查找、填充、复制、数组转集合、比较/哈希
线程安全提供同步化包装方法
不可变封装提供 emptyXXX/singletonXXX/unmodifiableXXX仅 asList 返回固定大小 List
集合转数组无(集合自身有 toArray() 方法)无(提供数组转集合)

四、常见避坑总结

  1. 不可变集合修改Collections.unmodifiableXXXArrays.asList 返回的集合,调用 add/remove 均会抛 UnsupportedOperationException
  2. Collections.copy 容量:目标 List 需提前初始化大小(size()),而非仅指定容量;
  3. Arrays.asList 基本类型:避免直接传入 int[]/long[] 等基本类型数组,需转为 Integer[]/Long[]
  4. 二分查找前置条件:无论是 Collections.binarySearch 还是 Arrays.binarySearch,必须先对目标排序;
  5. 同步化集合迭代Collections.synchronizedXXX 返回的集合,迭代时需手动加锁,否则可能出现并发修改异常。
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐