Java Collections & Arrays 工具类
·
一、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 对比
| 维度 | Collections | Arrays |
|---|---|---|
| 操作对象 | List、Set、Map(集合) | 基本类型数组、对象数组 |
| 核心功能 | 排序(仅List)、查找、填充、同步化、不可变封装 | 排序(所有数组)、查找、填充、复制、数组转集合、比较/哈希 |
| 线程安全 | 提供同步化包装方法 | 无 |
| 不可变封装 | 提供 emptyXXX/singletonXXX/unmodifiableXXX | 仅 asList 返回固定大小 List |
| 集合转数组 | 无(集合自身有 toArray() 方法) | 无(提供数组转集合) |
四、常见避坑总结
- 不可变集合修改:
Collections.unmodifiableXXX和Arrays.asList返回的集合,调用add/remove均会抛UnsupportedOperationException; - Collections.copy 容量:目标 List 需提前初始化大小(
size()),而非仅指定容量; - Arrays.asList 基本类型:避免直接传入
int[]/long[]等基本类型数组,需转为Integer[]/Long[]; - 二分查找前置条件:无论是
Collections.binarySearch还是Arrays.binarySearch,必须先对目标排序; - 同步化集合迭代:
Collections.synchronizedXXX返回的集合,迭代时需手动加锁,否则可能出现并发修改异常。
更多推荐


所有评论(0)