Java 数组

更新于 2025-12-25

Jakob Jenkov 发布于 2019-04-24

Java 数组(Array)是相同类型变量的集合。例如,一个 int 类型的数组就是多个 int 变量的集合。数组中的变量是有序的,每个元素都有一个索引(下标)。稍后你将看到如何通过索引来访问数组元素。

下图展示了 Java 数组的基本结构:

Java Arrays

声明 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 的数组,其有效索引为 09

你可以像使用普通变量一样使用数组元素:读取、赋值、参与计算、作为方法参数传递等。

获取数组长度

通过 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(顺序不同)