Java 数组详细教程

数组是 Java 中一种基本且重要的数据结构,用于存储固定大小的同类型元素的集合。所有元素在内存中是连续存储的,可以通过索引(下标)快速访问。

1. 数组的基本概念

  • 元素: 数组中存储的每一个数据项。
  • 长度: 数组一旦创建,其长度(元素个数)就是固定的,不可改变。可以通过 数组名.length 属性获取。
  • 索引: 用于访问数组元素的序号。Java 数组的索引从 0 开始,到 长度 - 1 结束。
  • 类型: 数组中所有元素必须是相同的数据类型(基本数据类型或引用类型)。

2. 声明数组

声明数组变量,告诉编译器数组的名称和它将包含的元素类型。此时并未分配内存空间。

语法:

数据类型[] 数组名; // 推荐方式
// 或
数据类型 数组名[]; // 效果相同,但不推荐,易与类型声明混淆

示例:

int[] numbers; // 声明一个整型数组引用变量 numbers
String[] names; // 声明一个字符串数组引用变量 names
double grades[]; // 声明一个双精度浮点型数组引用变量 grades (不推荐写法)

3. 创建数组(分配内存)

使用 new 关键字在堆内存中为数组分配空间,并指定长度。

语法:

数组名 = new 数据类型[数组长度];

也可以将声明和创建合并在一行:

数据类型[] 数组名 = new 数据类型[数组长度];

示例:

numbers = new int[5]; // 为 numbers 分配一个能存储 5 个整数的空间
String[] names = new String[3]; // 声明并创建一个能存储 3 个字符串引用的数组

4. 初始化数组

在创建数组的同时,为其元素赋初值。

方式一:创建时指定元素值

语法:

数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, ..., 元素n};
// 简写形式 (只能在声明时使用):
数据类型[] 数组名 = {元素1, 元素2, ..., 元素n};

示例:

int[] scores = new int[]{90, 85, 78, 92, 88}; // 创建并初始化
int[] primes = {2, 3, 5, 7, 11}; // 简写形式,创建并初始化

方式二:先创建后赋值

使用索引逐个或循环赋值。

int[] arr = new int[3];
arr[0] = 10; // 为第一个元素赋值
arr[1] = 20; // 为第二个元素赋值
arr[2] = 30; // 为第三个元素赋值

5. 访问数组元素

通过索引访问数组元素。索引范围是 [0, 数组名.length - 1]

语法:

数组名[索引]

示例:

int firstScore = scores[0]; // 访问 scores 数组的第一个元素
names[1] = "李四"; // 修改 names 数组的第二个元素

重要: 访问超出索引范围的元素会导致 ArrayIndexOutOfBoundsException 运行时异常。

6. 遍历数组

遍历数组就是访问数组中的每一个元素。常用方法有:

使用 for 循环 (索引遍历)

for (int i = 0; i < 数组名.length; i++) {
    // 操作 数组名[i]
}

示例:

int[] numbers = {5, 10, 15, 20};
for (int i = 0; i < numbers.length; i++) {
    System.out.println("元素 " + i + ": " + numbers[i]);
}

使用增强 for 循环 (for-each 循环,值遍历)

更简洁,适用于只需要元素值,不需要索引的情况。

for (数据类型 元素变量 : 数组名) {
    // 操作 元素变量
}

示例:

String[] fruits = {"Apple", "Banana", "Orange"};
for (String fruit : fruits) {
    System.out.println(fruit);
}

7. 多维数组

Java 支持多维数组,最常见的是二维数组(可以看作表格)。

二维数组声明与创建

数据类型[][] 数组名; // 声明
数组名 = new 数据类型[行数][列数]; // 创建(指定列数)
// 或
数组名 = new 数据类型[行数][]; // 创建(不指定列数,每行可不同长)

示例:

int[][] matrix = new int[3][4]; // 3行4列的整型二维数组
String[][] table; // 声明
table = new String[2][]; // 2行,每行的列数待定
table[0] = new String[3]; // 第一行有3列
table[1] = new String[2]; // 第二行有2列

二维数组初始化

int[][] grid = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
}; // 3x3 数组

二维数组遍历

嵌套循环。

for (int i = 0; i < grid.length; i++) { // 遍历行
    for (int j = 0; j < grid[i].length; j++) { // 遍历当前行的列
        System.out.print(grid[i][j] + " ");
    }
    System.out.println(); // 换行
}

8. 数组的常见操作与注意事项

  • 复制数组:
    • System.arraycopy(源数组, 源起始索引, 目标数组, 目标起始索引, 复制长度)
    • Arrays.copyOf(源数组, 新长度)
    • Arrays.copyOfRange(源数组, 起始索引, 结束索引)
    • clone() 方法 (数组实现了 Cloneable)
  • 数组排序: Arrays.sort(数组名)
  • 数组查找: Arrays.binarySearch(数组名, 要查找的值) (要求数组已排序)
  • 数组比较: Arrays.equals(数组1, 数组2)
  • 数组转字符串: Arrays.toString(一维数组) / Arrays.deepToString(多维数组)
  • 长度固定: 数组长度一旦确定就不能改变。如果需要动态大小,考虑使用 ArrayList
  • 内存管理: 数组是对象,存储在堆内存中。数组变量存储的是对数组对象的引用。
  • 默认值: 创建数组后,元素会被赋予默认值(如 int 为 0,booleanfalse,引用类型为 null)。
  • 越界检查: 务必注意索引范围,避免 ArrayIndexOutOfBoundsException

9. 数组的应用场景

  • 存储一组相关的数据(如学生成绩、商品列表)。
  • 实现数据结构(如栈、队列的底层实现)。
  • 作为方法的参数或返回值。
  • 用于算法实现(如排序、查找)。

示例代码:数组求和与查找最大值

public class ArrayExample {
    public static void main(String[] args) {
        // 创建并初始化数组
        int[] values = {12, 5, 23, 8, 17};

        // 计算总和
        int sum = 0;
        for (int value : values) {
            sum += value;
        }
        System.out.println("数组总和: " + sum);

        // 查找最大值
        int max = values[0];
        for (int i = 1; i < values.length; i++) {
            if (values[i] > max) {
                max = values[i];
            }
        }
        System.out.println("最大值: " + max);

        // 使用 Arrays 类排序
        java.util.Arrays.sort(values);
        System.out.println("排序后: " + java.util.Arrays.toString(values));
    }
}

总结

Java 数组是存储固定大小同类型元素集合的高效工具。掌握数组的声明、创建、初始化、访问、遍历以及常见操作是 Java 编程的基础。理解其内存结构和特性(长度固定、索引从 0 开始)对于避免常见错误至关重要。对于需要动态大小的场景,应转向集合框架(如 ArrayList)。

更多推荐