Jakob Jenkov 发布于 2019-04-24
Java 数组(Array)是相同类型变量的集合。例如,一个 int 类型的数组就是多个 int 变量的集合。数组中的变量是有序的,每个元素都有一个索引(下标)。稍后你将看到如何通过索引来访问数组元素。
下图展示了 Java 数组的基本结构:

声明 Java 数组变量
声明 Java 数组变量的方式与声明普通变量类似,只需在类型后面加上一对方括号 []。例如:
int[] intArray;
你可以将 Java 数组用作字段、静态字段、局部变量或方法参数,就像使用其他任何变量一样。数组只是数据类型的一种变体——它不是单个变量,而是一组同类型的变量。
更多声明示例:
String[] stringArray;
MyClass[] myClassArray;
- 第一行声明了一个
String引用的数组。 - 第二行声明了一个指向自定义类
MyClass对象的引用数组。
实际上,在 Java 中声明数组时,方括号 [] 的位置可以有两种选择:
- 放在类型后面(如
String[]) - 放在变量名后面(如
String stringArray[])
以下所有写法都是合法的:
int[] intArray;
int intArray[];
String[] stringArray;
String stringArray[];
MyClass[] myClassArray;
MyClass myClassArray[];
个人建议:将
[]放在类型之后(如String[]),因为数组本质上是一种特殊的类型,这样写代码更清晰易读。
实例化 Java 数组
声明数组变量只是声明了一个引用,并不会创建实际的数组对象。你需要使用 new 关键字来创建数组:
int[] intArray;
intArray = new int[10];
这行代码创建了一个能容纳 10 个 int 元素的数组。
你也可以创建对象引用的数组:
String[] stringArray = new String[10];
Java 允许为任意类型的对象创建引用数组。
Java 数组字面量(Array Literals)
如果在创建数组时已知所有元素的值,可以使用数组字面量语法:
int[] ints2 = new int[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
花括号 {} 中的值列表决定了数组的内容和长度。
在较新版本的 Java 中,甚至可以省略 new int[] 部分:
int[] ints2 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
这种写法适用于所有基本类型和 String 类型:
String[] strings = {"one", "two", "three"};
Java 数组长度不可变
一旦创建,Java 数组的大小就不能改变。某些语言(如 JavaScript)支持动态调整数组大小,但 Java 不支持。
如果你需要可变大小的“数组”,应考虑使用 List,或者实现一个 可调整大小的 Java 数组。在某些场景下,也可以使用基于数组实现的 Java 环形缓冲区(RingBuffer)。
访问 Java 数组元素
数组中的每个变量称为一个“元素”。可以通过索引访问每个元素:
intArray[0] = 0; // 赋值
int firstInt = intArray[0]; // 读取
数组索引从 0 开始,到 length - 1 结束。例如,长度为 10 的数组,其有效索引为 0 到 9。
你可以像使用普通变量一样使用数组元素:读取、赋值、参与计算、作为方法参数传递等。
获取数组长度
通过 length 字段可以获取数组长度:
int[] intArray = new int[10];
int arrayLength = intArray.length; // 值为 10
遍历数组
使用 for 循环
String[] stringArray = new String[10];
// 初始化
for (int i = 0; i < stringArray.length; i++) {
stringArray[i] = "String no " + i;
}
// 打印
for (int i = 0; i < stringArray.length; i++) {
System.out.println(stringArray[i]);
}
对于基本类型(如 int):
int[] intArray = new int[10];
for (int i = 0; i < intArray.length; i++) {
intArray[i] = i;
}
for (int i = 0; i < intArray.length; i++) {
System.out.println(intArray[i]);
}
使用 for-each 循环(增强 for)
int[] intArray = new int[10];
for (int theInt : intArray) {
System.out.println(theInt);
}
⚠️ 注意:for-each 循环只能读取元素值,不能修改数组内容,也无法获取当前元素的索引。如需修改或知道索引,请使用普通 for 循环。
对象数组同样适用:
String[] stringArray = {"one", "two", "three"};
for (String theString : stringArray) {
System.out.println(theString);
}
多维数组
Java 支持多维数组。每增加一维,就在类型后加一对 []:
int[][] intArray = new int[10][20];
这表示一个包含 10 个 int[] 数组的数组,每个子数组有 20 个 int 元素。
访问元素需要多个索引:
intArray[0][2] = 129;
int oneInt = intArray[0][2];
遍历多维数组
需要嵌套循环:
int[][] intArray = new int[10][20];
for (int i = 0; i < intArray.length; i++) {
for (int j = 0; j < intArray[i].length; j++) {
System.out.println("i: " + i + ", j: " + j);
}
}
向数组中插入元素
Java 数组本身不支持插入操作(因为长度固定),但可以通过移动元素模拟插入:
int[] ints = new int[20];
int insertIndex = 10;
int newValue = 123;
// 将插入点之后的元素后移一位(最后一个元素会被覆盖)
for (int i = ints.length - 1; i > insertIndex; i--) {
ints[i] = ints[i - 1];
}
// 插入新值
ints[insertIndex] = newValue;
System.out.println(Arrays.toString(ints));
可封装为方法:
public void insertIntoArray(int[] array, int insertIndex, int newValue) {
for (int i = array.length - 1; i > insertIndex; i--) {
array[i] = array[i - 1];
}
array[insertIndex] = newValue;
}
注意:此操作会丢失最后一个元素!且要求
insertIndex在有效范围内。
从数组中删除元素
同样通过移动元素实现“删除”:
int[] ints = new int[20];
ints[10] = 123;
int removeIndex = 10;
// 将删除点之后的元素前移一位
for (int i = removeIndex; i < ints.length - 1; i++) {
ints[i] = ints[i + 1];
}
// 最后一个元素会重复(未清除)
封装为方法:
public void removeFromArray(int[] array, int removeIndex) {
for (int i = removeIndex; i < array.length - 1; i++) {
array[i] = array[i + 1];
}
}
注意:数组长度不变,最后一个元素未被清除。
查找数组中的最小值和最大值
Java 没有内置函数,需手动实现。
最小值
int[] ints = {0, 2, 4, 6, 8, 10};
int minVal = Integer.MAX_VALUE;
for (int i = 0; i < ints.length; i++) {
if (ints[i] < minVal) {
minVal = ints[i];
}
}
System.out.println("minVal = " + minVal); // 输出 0
最大值
int[] ints = {0, 2, 4, 6, 8, 10};
int maxVal = Integer.MIN_VALUE;
for (int i = 0; i < ints.length; i++) {
if (ints[i] > maxVal) {
maxVal = ints[i];
}
}
System.out.println("maxVal = " + maxVal); // 输出 10
Arrays 工具类
Java 提供了 java.util.Arrays 工具类,用于执行常见数组操作(复制、排序、填充、搜索等)。
使用前需导入:
import java.util.Arrays;
复制数组
方法 1:手动遍历
int[] source = new int[10];
int[] dest = new int[10];
for (int i = 0; i < source.length; i++) {
source[i] = i;
}
for (int i = 0; i < source.length; i++) {
dest[i] = source[i];
}
方法 2:Arrays.copyOf()
int[] dest = Arrays.copyOf(source, source.length);
第二个参数指定新数组长度,可用于截断或扩展(扩展时补默认值)。
方法 3:Arrays.copyOfRange()
复制指定范围 [from, to):
int[] dest = Arrays.copyOfRange(source, 0, source.length);
将数组转为字符串:Arrays.toString()
int[] ints = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
System.out.println(Arrays.toString(ints));
// 输出:[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
排序数组:Arrays.sort()
对基本类型数组按自然顺序排序:
int[] ints = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
Arrays.sort(ints);
System.out.println(Arrays.toString(ints));
// 输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
排序对象数组
对象没有自然顺序,需提供 Comparator:
private static class Employee {
public String name;
public int employeeId;
public Employee(String name, int employeeId) {
this.name = name;
this.employeeId = employeeId;
}
}
Employee[] employees = {
new Employee("Xander", 1),
new Employee("John", 3),
new Employee("Anna", 2)
};
// 按姓名排序
Arrays.sort(employees, new Comparator<Employee>() {
@Override
public int compare(Employee e1, Employee e2) {
return e1.name.compareTo(e2.name);
}
});
// 按 ID 排序
Arrays.sort(employees, new Comparator<Employee>() {
@Override
public int compare(Employee e1, Employee e2) {
return e1.employeeId - e2.employeeId;
}
});
// 先按姓名,再按 ID
Arrays.sort(employees, new Comparator<Employee>() {
@Override
public int compare(Employee e1, Employee e2) {
int nameDiff = e1.name.compareTo(e2.name);
if (nameDiff != 0) return nameDiff;
return e1.employeeId - e2.employeeId;
}
});
填充数组:Arrays.fill()
将整个数组填充为指定值:
int[] intArray = new int[10];
Arrays.fill(intArray, 123);
// 结果:[123, 123, ..., 123]
也可填充部分区间 [from, to):
Arrays.fill(intArray, 3, 5, 123);
// 索引 3 和 4 被设为 123
二分查找:Arrays.binarySearch()
前提:数组必须已排序!
int[] ints = {0, 2, 4, 6, 8, 10};
int index = Arrays.binarySearch(ints, 6); // 返回 3
- 找到:返回索引(≥0)
- 未找到:返回
-(插入点) - 1- 例如,查找
7应插入索引4,返回-5 - 若所有元素都小于目标值,返回
-length - 1(如查找12返回-7)
- 例如,查找
也可搜索子区间 [from, to):
int index = Arrays.binarySearch(ints, 0, 4, 2); // 在 [0,4) 中查找 2
判断数组是否相等:Arrays.equals()
两个数组相等当且仅当:
- 长度相同
- 所有对应元素相等(按顺序)
int[] a = {0, 2, 4, 6, 8, 10};
int[] b = {0, 2, 4, 6, 8, 10};
int[] c = {10, 8, 6, 4, 2, 0};
System.out.println(Arrays.equals(a, b)); // true
System.out.println(Arrays.equals(a, c)); // false(顺序不同)