1. 引言
本教程将深入探讨 Java 语言中的一个核心概念 —— 数组(Array)。
我们将从数组的定义开始,逐步讲解如何使用数组,并覆盖以下内容:
- ✅ 数组的初始化和基本操作
- ✅ 如何读写数组元素
- ✅ 遍历数组的方式
- ✅ 将数组转换为其他对象类型,如
List
或Stream
- ✅ 对数组进行排序、查找和合并等进阶操作
2. 什么是数组?
根据 Java 官方文档,数组是一个包含固定数量相同类型的值的对象。数组中的每个元素都有索引(index),这意味着我们可以通过数字来访问它们。
你可以把数组想象成一个编号的单元格列表,每个单元格存储一个值。在 Java 中,索引从 0 开始。
数组分为两种类型:
- 基本数据类型数组(如
int[]
,float[]
,boolean[]
等) - 对象类型数组(如
String[]
,Object[]
,以及自定义类的数组)
3. 创建数组
3.1. 声明数组
Java 中有两种声明数组的方式:
int[] anArray;
或者:
int anOtherArray[];
✅ 推荐使用第一种方式,更加清晰易懂。
3.2. 初始化数组
初始化数组也有多种方式:
方式一:指定大小,默认值初始化
int[] anArray = new int[10];
这会创建一个包含 10 个 int
元素的数组,默认值为 0。如果是对象数组,默认值为 null
。
方式二:直接赋值初始化
int[] anArray = new int[] {1, 2, 3, 4, 5};
这种方式无需指定长度,数组长度自动根据大括号中的元素数量确定。
4. 获取数组长度
数组的长度是固定的,创建后不能修改。可以通过 .length
属性获取数组长度:
int[] anArray = new int[] { 1, 2, 3, 4, 5 };
System.out.println("anArray's length: " + anArray.length);
输出:
anArray's length: 5
另外,也可以使用反射类中的 Array.getLength()
方法:
System.out.println("[Array.getLength()] anArray's length: " + Array.getLength(anArray));
输出:
[Array.getLength()] anArray's length: 5
⚠️ 注意:Array.getLength()
接收的是 Object
类型参数,适用于泛型或反射场景。
5. 访问数组元素
通过索引访问数组元素:
anArray[0] = 10;
System.out.println(anArray[0]);
输出:
10
⚠️ 如果索引小于 0 或大于等于数组长度,会抛出 ArrayIndexOutOfBoundsException
。
6. 遍历数组
6.1. 使用 for 循环
int[] anArray = new int[] {1, 2, 3, 4, 5};
for (int i = 0; i < anArray.length; i++) {
System.out.println(anArray[i]);
}
6.2. 使用 foreach 循环
int[] anArray = new int[] {1, 2, 3, 4, 5};
for (int element : anArray) {
System.out.println(element);
}
✅ foreach 循环适用于不需索引、也不需修改数组元素的场景。
7. 可变参数(Varargs)
可变参数在方法中会被当作数组处理:
void varargsMethod(String... varargs) {}
调用时可以传入多个参数,也可以直接传入一个数组:
String[] anArray = new String[] {"Milk", "Tomato", "Chips"};
varargsMethod(anArray);
等价于:
varargsMethod("Milk", "Tomato", "Chips");
8. 数组转 List
8.1. 手动遍历转换
int[] anArray = new int[] {1, 2, 3, 4, 5};
List<Integer> aList = new ArrayList<>();
for (int element : anArray) {
aList.add(element);
}
8.2. 使用 Arrays.asList()
Integer[] anArray = new Integer[] {1, 2, 3, 4, 5};
List<Integer> aList = Arrays.asList(anArray);
⚠️ 注意事项:
- ❌ 不能用于基本类型数组
- ❌ 返回的 List 不能添加或删除元素,否则抛出
UnsupportedOperationException
9. 数组转 Stream
Java 8 引入了 Stream
API,可以通过 Arrays.stream()
方法将数组转换为流:
String[] anArray = new String[] {"Milk", "Tomato", "Chips"};
Stream<String> aStream = Arrays.stream(anArray);
也可以只对数组的一部分创建流:
Stream<String> anotherStream = Arrays.stream(anArray, 1, 3);
这将创建一个包含 "Tomato"
和 "Chips"
的流。
10. 数组排序
Java 提供了 Arrays.sort()
方法用于排序:
int[] anArray = new int[] {5, 2, 1, 4, 8};
Arrays.sort(anArray); // 结果为 {1, 2, 4, 5, 8}
✅ 支持:
- 基本类型数组(升序)
- 实现
Comparable
接口的对象数组 - 自定义
Comparator
排序 - 指定范围排序
示例:
String[] yetAnotherArray = new String[] {"A", "E", "Z", "B", "C"};
Arrays.sort(yetAnotherArray, 1, 3, Comparator.comparing(String::toString).reversed());
// 结果为 {"A", "Z", "E", "B", "C"}
11. 数组查找
11.1. 普通遍历查找
int[] anArray = new int[] {5, 2, 1, 4, 8};
for (int i = 0; i < anArray.length; i++) {
if (anArray[i] == 4) {
System.out.println("Found at index " + i);
break;
}
}
11.2. 二分查找(适用于已排序数组)
int[] anArray = new int[] {1, 2, 3, 4, 5};
int index = Arrays.binarySearch(anArray, 4);
System.out.println("Found at index " + index);
输出:
Found at index 3
12. 数组合并
12.1. 手动合并
int[] anArray = new int[] {5, 2, 1, 4, 8};
int[] anotherArray = new int[] {10, 4, 9, 11, 2};
int[] resultArray = new int[anArray.length + anotherArray.length];
for (int i = 0; i < resultArray.length; i++) {
resultArray[i] = (i < anArray.length ? anArray[i] : anotherArray[i - anArray.length]);
}
12.2. 使用 Arrays.setAll
Arrays.setAll(resultArray, i -> (i < anArray.length ? anArray[i] : anotherArray[i - anArray.length]));
12.3. 使用 System.arraycopy
System.arraycopy(anArray, 0, resultArray, 0, anArray.length);
System.arraycopy(anotherArray, 0, resultArray, anArray.length, anotherArray.length);
13. 总结
本文详细讲解了 Java 中数组的基础和进阶用法。Java 提供了强大的 Arrays
工具类来处理数组操作,同时也支持通过 Apache Commons、Guava 等库进行扩展。
完整的代码示例可在 GitHub 仓库 中查看。