Collections和Arrays

一、Collections 工具类

概念

java.util.Collections 是一个工具类,提供各种操作集合的静态方法(不可以被实例化,因为构造方法是私有的)

Collections和Collection的区别

方面 Collection (接口) Collections (工具类)
类型 接口 (interface) 工具类 (final class)
包位置 java.util.Collection java.util.Collections
主要作用 定义集合的基本操作规范 提供操作集合的实用静态方法
实例化 不能实例化,需要实现类 不能实例化(构造器私有)
方法特点 抽象方法,需要子类实现 静态方法,直接调用
使用方式 多态,通过实现类使用 工具类,直接Collections.xxx() 调用
继承关系 集合框架的根接口之一 不继承任何接口,final class
设计模式 接口模式,定义规范 工具类模式,提供实用方法

特点:

  • 所有的方法都是静态的
  • 主要操作List、Map、Set等集合
  • 提供空集合和单元素集合
  • 包含排序、搜索、同步包装、不可修改包装等方法

常用方法

1、排序和查找相关方法

1. sort() - 排序
java 复制代码
// 自然排序(元素必须实现 Comparable)
List<Integer> numbers = new ArrayList<>(Arrays.asList(3, 1, 4, 1, 5));
Collections.sort(numbers); // [1, 1, 3, 4, 5]

// 自定义比较器排序
List<String> names = new ArrayList<>(Arrays.asList("John", "Alice", "Bob"));
Collections.sort(names, Comparator.reverseOrder()); // [John, Bob, Alice]

// 按字符串长度排序
Collections.sort(names, Comparator.comparingInt(String::length));

注意事项:需要配合Comparator使用

2. binarySearch() - 二分查找
java 复制代码
List<Integer> sortedList = Arrays.asList(1, 3, 5, 7, 9);
// 前提:列表必须是有序的
int index = Collections.binarySearch(sortedList, 5); // 2
int notFound = Collections.binarySearch(sortedList, 4); // -3

// 自定义比较器的二分查找
List<String> words = Arrays.asList("apple", "banana", "cherry");
Collections.sort(words);
int idx = Collections.binarySearch(words, "banana"); // 1

注意事项:需要进行排序

3. reverse() - 反转
java 复制代码
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Collections.reverse(list); // [5, 4, 3, 2, 1]
4. shuffle() - 随机打乱
java 复制代码
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Collections.shuffle(list); // 随机顺序,如 [3, 1, 5, 2, 4]

// 使用指定随机源
Random random = new Random(42);
Collections.shuffle(list, random); // 可重现的随机顺序
5. swap() - 交换元素
java 复制代码
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C", "D"));
Collections.swap(list, 0, 3); // ["D", "B", "C", "A"]

注意事项:在原列表中进行操作不会创建出新的列表

6. rotate() - 旋转
java 复制代码
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Collections.rotate(list, 2); // [4, 5, 1, 2, 3] 向右旋转2位
Collections.rotate(list, -1); // [5, 1, 2, 3, 4] 向左旋转1位

2、最大最小值查找

7. max() / min() - 查找最大最小值
java 复制代码
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5);

// 自然顺序
Integer max = Collections.max(numbers); // 5
Integer min = Collections.min(numbers); // 1

// 自定义比较器
Integer maxByCustom = Collections.max(numbers, 
    (a, b) -> Integer.compare(a % 3, b % 3));

// 字符串最长/最短
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
String longest = Collections.max(names, Comparator.comparingInt(String::length)); // Charlie
String shortest = Collections.min(names, Comparator.comparingInt(String::length)); // Bob

注意事项:需要配合Comparator使用

3、频率和位置操作

8. frequency() - 统计频率
java 复制代码
List<String> words = Arrays.asList("apple", "banana", "apple", "orange", "apple");
int freq = Collections.frequency(words, "apple"); // 3
int freq2 = Collections.frequency(words, "banana"); // 1

// 在 Set 中使用
Set<Integer> numbers = new HashSet<>(Arrays.asList(1, 2, 1, 3, 2));
int freq3 = Collections.frequency(numbers, 2); // 1(Set 中每个元素只出现一次)
9. indexOfSubList() / lastIndexOfSubList() - 查找子列表
java 复制代码
List<Integer> source = Arrays.asList(1, 2, 3, 4, 1, 2, 3, 4);
List<Integer> target = Arrays.asList(2, 3);

int first = Collections.indexOfSubList(source, target); // 1
int last = Collections.lastIndexOfSubList(source, target); // 5

4、填充和替换操作

10. fill() - 填充
java 复制代码
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c", "d"));
Collections.fill(list, "X"); // ["X", "X", "X", "X"]

// 注意:会替换所有元素
List<Integer> numbers = new ArrayList<>(Collections.nCopies(5, null));
Collections.fill(numbers, 0); // [0, 0, 0, 0, 0]

注意事项:常使用于初始化

11. replaceAll() - 替换所有
java 复制代码
List<String> list = new ArrayList<>(Arrays.asList("foo", "bar", "foo", "test"));
boolean changed = Collections.replaceAll(list, "foo", "FOO"); // true
// 结果:["FOO", "bar", "FOO", "test"]

// 如果没有匹配项
boolean changed2 = Collections.replaceAll(list, "none", "NEW"); // false

注意事项:不会创建出来新数组

12. nCopies() - 创建多个副本
java 复制代码
List<String> copies = Collections.nCopies(3, "Hello");
// ["Hello", "Hello", "Hello"]
// 注意:返回的是不可变列表

// 常见用法:初始化列表
List<String> list = new ArrayList<>(Collections.nCopies(10, ""));

5、不可修改和同步包装

13. unmodifiableXxx() - 不可修改视图
java 复制代码
List<String> original = new ArrayList<>(Arrays.asList("A", "B", "C"));
List<String> unmodifiableList = Collections.unmodifiableList(original);

// 可以读取
String first = unmodifiableList.get(0); // "A"

// 不能修改
// unmodifiableList.add("D"); // UnsupportedOperationException
// unmodifiableList.set(0, "X"); // UnsupportedOperationException

// 原始列表修改会影响视图
original.add("D");
System.out.println(unmodifiableList.size()); // 4
14. synchronizedXxx() - 同步包装
java 复制代码
// 创建线程安全的集合
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
Map<String, String> syncMap = Collections.synchronizedMap(new HashMap<>());
Set<Integer> syncSet = Collections.synchronizedSet(new HashSet<>());

// 使用时需要注意
// 正确做法:迭代时需要手动同步
synchronized(syncList) {
    Iterator<String> it = syncList.iterator();
    while (it.hasNext()) {
        System.out.println(it.next());
    }
}

注意事项:常用,用于线程安全

15. checkedXxx() - 类型安全包装
java 复制代码
// 创建类型安全的集合
List list = new ArrayList();
List<String> checkedList = Collections.checkedList(list, String.class);

// 现在添加错误类型会立即抛出异常
checkedList.add("Hello"); // OK
// checkedList.add(123); // ClassCastException(立即抛出)

// 适用于调试和防止类型污染

6、单元素和空集合

16. singleton() / singletonList() / singletonMap() - 单元素集合
java 复制代码
Set<String> singleSet = Collections.singleton("unique");
List<Integer> singleList = Collections.singletonList(42);
Map<String, Integer> singleMap = Collections.singletonMap("key", 100);

// 这些集合都是不可修改的
// singleSet.add("another"); // UnsupportedOperationException

// 实用场景:从集合中移除特定元素
list.removeAll(Collections.singleton("removeMe"));
17. emptyXxx() - 空集合
java 复制代码
// 安全的空集合
List<String> emptyList = Collections.emptyList();
Set<Integer> emptySet = Collections.emptySet();
Map<String, Object> emptyMap = Collections.emptyMap();

// 最佳实践:避免返回 null
public List<String> getNames() {
    if (condition) {
        return names;
    }
    return Collections.emptyList(); // 而不是 null
}

// 不可修改
// emptyList.add("item"); // UnsupportedOperationException

7、集合操作

18. addAll() - 批量添加
java 复制代码
List<String> list = new ArrayList<>();
Collections.addAll(list, "A", "B", "C", "D"); // [A, B, C, D]

// 比 list.add("A"); list.add("B"); ... 更简洁
// 比 Arrays.asList("A", "B", "C", "D") 更高效(避免中间集合)

// 可以添加数组
String[] moreItems = {"E", "F"};
Collections.addAll(list, moreItems); // [A, B, C, D, E, F]
19. copy() - 复制列表
java 复制代码
List<String> source = Arrays.asList("A", "B", "C");
List<String> dest = new ArrayList<>(Arrays.asList("1", "2", "3", "4", "5"));

// 目标列表必须至少和源列表一样长
Collections.copy(dest, source); // ["A", "B", "C", "4", "5"]

// 如果目标列表长度不够会抛出异常
// List<String> shortDest = new ArrayList<>(Arrays.asList("1", "2"));
// Collections.copy(shortDest, source); // IndexOutOfBoundsException

注意事项:浅拷贝

20. disjoint() - 检查是否无交集
java 复制代码
List<Integer> list1 = Arrays.asList(1, 2, 3);
List<Integer> list2 = Arrays.asList(4, 5, 6);
List<Integer> list3 = Arrays.asList(3, 4, 5);

boolean noCommon1 = Collections.disjoint(list1, list2); // true
boolean noCommon2 = Collections.disjoint(list1, list3); // false(有共同元素3)
21. reverseOrder() - 获取逆序比较器
java 复制代码
// 自然顺序的逆序
Comparator<Integer> reverseNatural = Collections.reverseOrder();

List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5);
numbers.sort(reverseNatural); // [5, 4, 3, 1, 1]

// 包装现有比较器
Comparator<String> byLength = Comparator.comparingInt(String::length);
Comparator<String> reverseByLength = Collections.reverseOrder(byLength);

二、Arrays工具类

Arrays 是 Java 中处理数组的核心工具类,提供了丰富的数组操作方法。

特点:

  • 所有方法都是静态的
  • 提供数组操作的各种工具方法
  • 支持基本类型数组和对象数组
  • 包含排序、搜索、比较、填充、转换等方法

常用方法

1、数组创建和初始化

1. asList() - 数组转列表
java 复制代码
// 基本用法
String[] arr = {"Java", "Python", "C++"};
List<String> list = Arrays.asList(arr);

// 直接传入元素
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

// 注意:返回的是固定大小的列表
// list.add("New"); // 抛出 UnsupportedOperationException
// list.remove(0); // 抛出 UnsupportedOperationException

// 但可以修改元素
list.set(0, "JavaScript"); // 允许

**注意事项:**asList返回的是固定大小的列表,不可以添加和删除

2. copyOf() - 数组复制
java 复制代码
int[] original = {1, 2, 3, 4, 5};

// 复制整个数组
int[] copy1 = Arrays.copyOf(original, original.length); // [1, 2, 3, 4, 5]

// 截断复制
int[] copy2 = Arrays.copyOf(original, 3); // [1, 2, 3]

// 扩展复制(多余位置填充默认值)
int[] copy3 = Arrays.copyOf(original, 7); // [1, 2, 3, 4, 5, 0, 0]

// 对象数组
String[] strArr = {"a", "b", "c"};
String[] strCopy = Arrays.copyOf(strArr, 5); // ["a", "b", "c", null, null]

注意事项:

  • 对于基本类型数组:是深拷贝(完全独立的副本)
  • 对于对象数组:是浅拷贝(只复制引用,不复制对象)
3. copyOfRange() - 范围复制
java 复制代码
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8};

// 复制指定范围 [from, to)
int[] range1 = Arrays.copyOfRange(arr, 2, 5); // [3, 4, 5]

// from 可以等于 to(空数组)
int[] range2 = Arrays.copyOfRange(arr, 3, 3); // []

// to 可以超过原数组长度
int[] range3 = Arrays.copyOfRange(arr, 5, 10); // [6, 7, 8, 0, 0]

注意事项:

  • 对于基本类型数组:是深拷贝(完全独立的副本)
  • 对于对象数组:是浅拷贝(只复制引用,不复制对象)

2、数组填充

4. fill() - 填充数组
java 复制代码
// 基本类型数组
int[] intArr = new int[5];
Arrays.fill(intArr, 42); // [42, 42, 42, 42, 42]

boolean[] boolArr = new boolean[3];
Arrays.fill(boolArr, true); // [true, true, true]

// 对象数组
String[] strArr = new String[4];
Arrays.fill(strArr, "Hello"); // ["Hello", "Hello", "Hello", "Hello"]

// 填充指定范围 [fromIndex, toIndex)
int[] arr = new int[6];
Arrays.fill(arr, 1, 4, 9); // [0, 9, 9, 9, 0, 0]

// 多用途示例
int[] scores = new int[10];
Arrays.fill(scores, -1); // 初始化分数为-1

注意事项:多用于初始化

3、数组排序

5. sort() - 数组排序
java 复制代码
// 基本类型排序(自然顺序)
int[] numbers = {5, 2, 9, 1, 7};
Arrays.sort(numbers); // [1, 2, 5, 7, 9]

// 对象数组排序(需要实现 Comparable)
String[] names = {"John", "Alice", "Bob"};
Arrays.sort(names); // ["Alice", "Bob", "John"]

// 部分排序
int[] arr = {9, 5, 3, 7, 1, 8};
Arrays.sort(arr, 2, 5); // 排序索引2到4:[9, 5, 1, 3, 7, 8]

// 自定义比较器(仅限对象数组)
String[] words = {"apple", "banana", "pear", "grape"};
Arrays.sort(words, Comparator.comparingInt(String::length));
// ["pear", "apple", "grape", "banana"]

// 降序排序
Integer[] nums = {5, 2, 9, 1, 7}; // 注意:必须用 Integer[] 而不是 int[]
Arrays.sort(nums, Comparator.reverseOrder()); // [9, 7, 5, 2, 1]

注意事项:需要配合Comparator使用

6. parallelSort() - 并行排序
java 复制代码
// 大数据量时使用并行排序更高效
int[] largeArray = new int[100000];
Random random = new Random();
for (int i = 0; i < largeArray.length; i++) {
    largeArray[i] = random.nextInt(1000000);
}

// 并行排序(适合多核处理器)
Arrays.parallelSort(largeArray);

// 也可以指定范围
Arrays.parallelSort(largeArray, 1000, 90000);

4、数组搜索

7. binarySearch() - 二分查找
java 复制代码
// 前提:数组必须是有序的!
int[] sortedArr = {1, 3, 5, 7, 9, 11};

// 查找存在的元素
int index1 = Arrays.binarySearch(sortedArr, 5); // 2
int index2 = Arrays.binarySearch(sortedArr, 1); // 0

// 查找不存在的元素(返回插入点的负值-1)
int index3 = Arrays.binarySearch(sortedArr, 4); // -3(插入点为2,返回-2-1)
int index4 = Arrays.binarySearch(sortedArr, 12); // -7(插入点为6,返回-6-1)

// 在指定范围内查找
int index5 = Arrays.binarySearch(sortedArr, 1, 4, 7); // 在索引1-3查找:3

// 对象数组二分查找(需要比较器)
String[] sortedNames = {"Alice", "Bob", "Charlie", "David"};
int idx = Arrays.binarySearch(sortedNames, "Charlie"); // 2

// 自定义比较器
String[] words = {"apple", "banana", "cherry", "date"};
Arrays.sort(words, Comparator.comparingInt(String::length));
int pos = Arrays.binarySearch(words, "fig", 
    Comparator.comparingInt(String::length)); // 查找长度为3的单词

注意事项:需要进行排序,才可以使用二分查找,要不没有作用

5、数组比较

8. equals() - 数组相等比较
java 复制代码
// 基本类型数组比较
int[] arr1 = {1, 2, 3};
int[] arr2 = {1, 2, 3};
int[] arr3 = {1, 2, 4};
boolean eq1 = Arrays.equals(arr1, arr2); // true
boolean eq2 = Arrays.equals(arr1, arr3); // false

// 对象数组比较(使用元素的 equals 方法)
String[] str1 = {"a", "b", "c"};
String[] str2 = {"a", "b", "c"};
String[] str3 = {"a", "b", "C"}; // 注意大小写
boolean seq1 = Arrays.equals(str1, str2); // true
boolean seq2 = Arrays.equals(str1, str3); // false

// 指定范围比较
int[] a1 = {1, 2, 3, 4, 5};
int[] a2 = {9, 2, 3, 4, 0};
boolean rangeEq = Arrays.equals(a1, 1, 4, a2, 1, 4); // true

注意事项:使用equals,比较逻辑和引用数据类型中自己定义的一样

9. deepEquals() - 深度比较(多维数组)
java 复制代码
// 一维数组可以用 equals,多维数组必须用 deepEquals
int[][] matrix1 = {{1, 2}, {3, 4}};
int[][] matrix2 = {{1, 2}, {3, 4}};
int[][] matrix3 = {{1, 2}, {3, 5}};

boolean deepEq1 = Arrays.deepEquals(matrix1, matrix2); // true
boolean deepEq2 = Arrays.deepEquals(matrix1, matrix3); // false

// 对象数组的深度比较
String[][] names1 = {{"Alice", "Bob"}, {"Charlie", "David"}};
String[][] names2 = {{"Alice", "Bob"}, {"Charlie", "David"}};
boolean namesEq = Arrays.deepEquals(names1, names2); // true

注意事项:多维度数组

6、数组转字符串

10. toString() - 数组转字符串
java 复制代码
// 基本类型数组
int[] intArr = {1, 2, 3};
String intStr = Arrays.toString(intArr); // "[1, 2, 3]"

// 对象数组
String[] strArr = {"Java", "Python"};
String strStr = Arrays.toString(strArr); // "[Java, Python]"

// 空数组
int[] empty = {};
String emptyStr = Arrays.toString(empty); // "[]"

// 调试输出
System.out.println("Array: " + Arrays.toString(arr));
11. deepToString() - 深度转字符串
java 复制代码
// 多维数组必须用 deepToString
int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
String matrixStr = Arrays.deepToString(matrix);
// "[[1, 2, 3], [4, 5, 6], [7, 8, 9]]"

// 对比 toString 的错误输出
System.out.println(Arrays.toString(matrix));
// 输出类似 "[[I@1b6d3586, [I@4554617c, [I@74a14482]"

// 对象多维数组
String[][] names = {{"Alice", "Bob"}, {"Charlie", "David"}};
String namesStr = Arrays.deepToString(names);
// "[[Alice, Bob], [Charlie, David]]"

注意事项:多维数组必须用 deepToString

7、哈希码和流操作

12. hashCode() / deepHashCode() - 哈希码
java 复制代码
// 一维数组哈希码
int[] arr = {1, 2, 3};
int hash1 = Arrays.hashCode(arr);

// 多维数组哈希码
int[][] matrix = {{1, 2}, {3, 4}};
int deepHash = Arrays.deepHashCode(matrix);

// 用于 HashMap 等集合
Map<int[], String> map = new HashMap<>();
map.put(arr, "value");
13. stream() - 数组转流
java 复制代码
// Java 8+ 将数组转为 Stream
int[] numbers = {1, 2, 3, 4, 5};

// IntStream
int sum = Arrays.stream(numbers).sum(); // 15
long count = Arrays.stream(numbers).count(); // 5
double avg = Arrays.stream(numbers).average().orElse(0); // 3.0

// 过滤和转换
int[] evenNumbers = Arrays.stream(numbers)
    .filter(n -> n % 2 == 0)
    .toArray(); // [2, 4]

// 对象数组
String[] names = {"Alice", "Bob", "Charlie"};
List<String> upperNames = Arrays.stream(names)
    .map(String::toUpperCase)
    .collect(Collectors.toList()); // [ALICE, BOB, CHARLIE]

// 范围流
int[] partialSum = Arrays.stream(numbers, 1, 4).toArray(); // [2, 3, 4]

8、高级和并行操作

14. parallelPrefix() - 并行前缀和
java 复制代码
// 计算前缀和(累加和)
int[] arr = {1, 2, 3, 4, 5};
Arrays.parallelPrefix(arr, (a, b) -> a + b);
// 结果:[1, 3, 6, 10, 15]

// 计算前缀积
int[] numbers = {1, 2, 3, 4, 5};
Arrays.parallelPrefix(numbers, (a, b) -> a * b);
// 结果:[1, 2, 6, 24, 120]

// 字符串连接
String[] words = {"Hello", " ", "World", "!"};
Arrays.parallelPrefix(words, (a, b) -> a + b);
// 结果:["Hello", "Hello ", "Hello World", "Hello World!"]
15. parallelSetAll() - 并行设置所有元素
java 复制代码
// 并行初始化数组
int[] squares = new int[10];
Arrays.parallelSetAll(squares, i -> i * i);
// 结果:[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

// 生成随机数
double[] randoms = new double[100];
Random random = new Random();
Arrays.parallelSetAll(randoms, i -> random.nextDouble());

// 生成序列
String[] sequence = new String[5];
Arrays.parallelSetAll(sequence, i -> "Item-" + (i + 1));
// 结果:["Item-1", "Item-2", "Item-3", "Item-4", "Item-5"]
16. setAll() - 设置所有元素
java 复制代码
// 顺序初始化(比 parallelSetAll 更适合小数组)
int[] arr = new int[5];
Arrays.setAll(arr, i -> i * 10);
// 结果:[0, 10, 20, 30, 40]

// 生成斐波那契数列
int[] fibonacci = new int[10];
Arrays.setAll(fibonacci, i -> {
    if (i < 2) return 1;
    return fibonacci[i-1] + fibonacci[i-2];
});
// 结果:[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
相关推荐
Yiii_x2 小时前
Object类与包装类
java·经验分享·笔记·课程设计·ai编程
吴名氏.2 小时前
电子书《Java程序设计与应用开发(第3版)》
java·开发语言·java程序设计与应用开发
于慨2 小时前
dayjs处理时区问题、前端时区问题
开发语言·前端·javascript
喵手2 小时前
数字处理的那些事:从 `Math` 到 `BigDecimal`,如何玩转数字与随机数?
java·数字处理
Wang15302 小时前
2025-2026 Java核心技术热点全景解析:从LTS革新到生态跃迁,筑牢后端技术核心竞争力
java
listhi5202 小时前
基于MATLAB的LTE系统仿真实现
开发语言·matlab
ss2732 小时前
ScheduledThreadPoolExecutor异常处理
java·开发语言
ssschema3 小时前
M4芯片MAC安装java环境
java·macos
星辰_mya3 小时前
RocketMQ
java·rocketmq·java-rocketmq