源本科技 | 码上会

Java 数组工具类 Arrays

2025/12/26
39
0

学习目标

  • 掌握 java.util.Arrays 类的核心功能与使用场景

  • 熟练运用排序、搜索、填充、比较等常用静态方法

  • 理解 asList() 在基本类型与引用类型上的行为差异

  • 能够使用高级特性如并行操作、流式处理和深度比较

  • 避免常见陷阱(如原始数组转 List 的误区)


为什么需要 Arrays 类?

Java 数组本身功能有限,不支持直接排序、查找或转换为字符串。java.util.Arrays 提供了一套高效、安全、标准化的工具方法,极大简化了数组操作。

关键特点

  • 所有方法均为 static,无需实例化

  • final 类,不可继承

  • 隐式继承自 Object

  • 专为工具用途设计

// 正确用法:直接调用静态方法
Arrays.sort(myArray);
Arrays.fill(data, 0);

核心方法详解

数组转集合

asList(T... a)

将数组转换为固定大小的 List(由 ArrayList 内部实现,非 java.util.ArrayList)。

正确用法(引用类型)

String[] fruits = {"苹果", "香蕉", "芒果"};
List<String> list = Arrays.asList(fruits);
System.out.println(list); // [苹果, 香蕉, 芒果]

常见陷阱(基本类型)

int[] nums = {1, 2, 3};
List<int[]> wrong = Arrays.asList(nums); // ❌ 将整个 int[] 视为一个对象
System.out.println(wrong); // [[I@19469ea2] —— 内存地址

解决方案:使用包装类型

Integer[] nums = {1, 2, 3};
List<Integer> correct = Arrays.asList(nums);
System.out.println(correct); // [1, 2, 3]

二分查找

binarySearch()

已排序数组中高效查找元素。

基础用法

int[] arr = {10, 15, 20, 22, 35};
Arrays.sort(arr); // 必须先排序!

int index = Arrays.binarySearch(arr, 22);
System.out.println("22 的索引: " + index); // 输出: 3

指定范围搜索

// 在索引 [1, 3) 范围内搜索(即只查 15, 20)
int index = Arrays.binarySearch(arr, 1, 3, 22);
System.out.println(index); // 输出: -4(负数表示未找到,插入点为 -(插入位置+1))

返回值规则

  • ≥ 0:找到,返回索引

  • < 0:未找到,返回 -(插入点 + 1)


排序

sort()

支持多种排序方式

基本排序

int[] numbers = {5, 2, 8, 1};
Arrays.sort(numbers); // 升序: [1, 2, 5, 8]

自定义比较器(对象数组)

String[] words = {"Java", "Python", "C++"};
Arrays.sort(words, (a, b) -> b.length() - a.length()); // 按长度降序
// 结果: ["Python", "Java", "C++"]

并行排序(大数据量)

Arrays.parallelSort(largeArray); // 利用多核 CPU 加速

填充数组

fill()

将指定值填入整个数组或指定范围。

int[] arr = new int[5];
Arrays.fill(arr, 7); // [7, 7, 7, 7, 7]

// 填充部分区域 [1, 4)
Arrays.fill(arr, 1, 4, 99); // [7, 99, 99, 99, 7]

数组比较

equals()deepEquals()

方法

适用场景

说明

equals(a, b)

一维数组

逐元素比较

deepEquals(a, b)

多维数组

递归比较所有层级

// 一维数组
int[] a1 = {1, 2, 3};
int[] a2 = {1, 2, 3};
System.out.println(Arrays.equals(a1, a2)); // true

// 二维数组
int[][] m1 = {{1, 2}, {3, 4}};
int[][] m2 = {{1, 2}, {3, 4}};
System.out.println(Arrays.deepEquals(m1, m2)); // true

数组转字符串

toString()deepToString()

方法

输出效果

Arrays.toString(arr)

[1, 2, 3]

Arrays.deepToString(matrix)

[[1, 2], [3, 4]]

int[] flat = {1, 2, 3};
System.out.println(Arrays.toString(flat)); // [1, 2, 3]

int[][] grid = {{1, 2}, {3, 4}};
System.out.println(Arrays.deepToString(grid)); // [[1, 2], [3, 4]]

比直接打印数组(如 System.out.println(arr))更直观


数组复制

copyOf()copyOfRange()

扩容或截断

int[] original = {1, 2, 3};
int[] larger = Arrays.copyOf(original, 5);   // [1, 2, 3, 0, 0]
int[] smaller = Arrays.copyOf(original, 2);  // [1, 2]

复制指定范围

int[] part = Arrays.copyOfRange(original, 1, 3); // [2, 3](左闭右开)

函数式编程支持

setAll()

按规则生成元素

int[] squares = new int[5];
Arrays.setAll(squares, i -> (i + 1) * (i + 1)); // [1, 4, 9, 16, 25]

parallelSetAll()

并行生成(大数据)

double[] randoms = new double[1000000];
Arrays.parallelSetAll(randoms, i -> Math.random());

stream()

转为 Stream

int[] data = {3, 1, 4, 1, 5};
long count = Arrays.stream(data)
                   .filter(x -> x > 2)
                   .count(); // 3

方法速查表

方法

功能

示例

sort(arr)

升序排序

Arrays.sort(scores)

binarySearch(arr, key)

二分查找

Arrays.binarySearch(sortedArr, 42)

fill(arr, val)

全部填充

Arrays.fill(flags, true)

equals(a, b)

一维数组相等判断

Arrays.equals(arr1, arr2)

deepEquals(a, b)

多维数组深度相等

Arrays.deepEquals(matrix1, matrix2)

toString(arr)

一维数组转字符串

Arrays.toString(ids)

deepToString(arr)

多维数组转字符串

Arrays.deepToString(table)

copyOf(arr, len)

复制并调整长度

Arrays.copyOf(data, 10)

asList(arr)

转为固定大小 List

Arrays.asList(names)

stream(arr)

转为 Stream

Arrays.stream(values).sum()

parallelSort(arr)

并行排序

Arrays.parallelSort(bigData)


典型应用场景

场景 1:快速初始化与验证

// 初始化成绩数组
int[] scores = new int[30];
Arrays.fill(scores, -1); // -1 表示未录入

// 录入后排序并查找
Arrays.sort(scores);
int pos = Arrays.binarySearch(scores, 85);

场景 2:多维数组深拷贝

int[][] original = {{1, 2}, {3, 4}};
int[][] copy = Arrays.stream(original)
                     .map(row -> row.clone())
                     .toArray(int[][]::new);

场景 3:调试友好输出

int[][] board = new int[8][8];
// ... 游戏逻辑 ...
System.out.println("当前棋盘:\n" + Arrays.deepToString(board));

注意事项

  1. binarySearch 前必须排序,否则结果不可预测

  2. asList 返回的 List 大小固定,不能 add()remove()

  3. 基本类型数组无法直接转为 List<基本类型>,需用包装类

  4. 多维数组比较务必用 deepEqualsequals 只比较引用

  5. 大数据量优先考虑 parallelSortparallelSetAll

  6. copyOfRangetoIndex 是左闭右开区间


重点总结

  • Arrays 是 Java 数组操作的瑞士军刀

  • 核心能力:排序、搜索、填充、比较、转换

  • 支持函数式编程并行处理

  • 处理多维数组时注意深度操作deepXXX

  • 避免原始类型与泛型的混淆(特别是 asList


思考题

  1. 为什么 Arrays.asList(new int[]{1,2,3}) 的结果不是 [1, 2, 3]?如何正确实现?

  2. 在什么情况下应该使用 Arrays.parallelSort() 而不是 Arrays.sort()

  3. 如何使用 Arrays 类实现一个“数组去重”功能?(提示:结合排序和流)