第18章

Java数组基础

掌握数组的声明、创建、初始化和基本操作方法

学习目标

什么是数组

数组是Java中最基本的数据结构之一,它是一个容器,可以存储多个相同类型的数据元素。数组中的每个元素都有一个索引(下标),通过索引可以访问和操作数组中的元素。

数组的特点

  • 类型统一:数组中所有元素必须是相同的数据类型
  • 长度固定:数组一旦创建,长度就不能改变
  • 索引访问:通过索引(从0开始)访问数组元素
  • 连续存储:数组元素在内存中连续存储

数组声明

在Java中,数组声明有两种语法形式,推荐使用第一种形式:

推荐语法

语法格式:
数据类型[] 数组名;
示例:
int[] numbers;        // 整型数组
String[] names;       // 字符串数组
double[] scores;      // 双精度数组
boolean[] flags;      // 布尔数组

备选语法

语法格式:
数据类型 数组名[];
示例:
int numbers[];        // 整型数组
String names[];       // 字符串数组
double scores[];      // 双精度数组
boolean flags[];      // 布尔数组

注意事项

数组声明时不能指定长度,长度是在创建数组时确定的。例如 int[5] arr; 是错误的语法。

数组创建

数组创建使用 new 关键字,需要指定数组的长度:

基本语法:
数组名 = new 数据类型[长度];
创建示例:
// 声明并创建数组
int[] numbers = new int[5];           // 创建长度为5的整型数组
String[] names = new String[10];      // 创建长度为10的字符串数组
double[] scores = new double[3];      // 创建长度为3的双精度数组

// 分步操作
int[] ages;                           // 先声明
ages = new int[8];                    // 后创建

默认值

数组创建后,所有元素都会被初始化为默认值:

各类型默认值:
int[] numbers = new int[3];        // [0, 0, 0]
double[] scores = new double[3];   // [0.0, 0.0, 0.0]
boolean[] flags = new boolean[3];  // [false, false, false]
String[] names = new String[3];    // [null, null, null]
char[] chars = new char[3];        // ['\u0000', '\u0000', '\u0000']

数组初始化

Java提供了多种数组初始化的方法:

静态初始化

在声明数组的同时指定初始值:

完整语法:
// 方式1:完整语法
int[] numbers = new int[]{1, 2, 3, 4, 5};
String[] names = new String[]{"张三", "李四", "王五"};
double[] scores = new double[]{85.5, 92.0, 78.5};

// 方式2:简化语法(推荐)
int[] numbers = {1, 2, 3, 4, 5};
String[] names = {"张三", "李四", "王五"};
double[] scores = {85.5, 92.0, 78.5};

动态初始化

先创建数组,然后逐个赋值:

动态赋值:
// 创建数组
int[] numbers = new int[5];

// 逐个赋值
numbers[0] = 10;
numbers[1] = 20;
numbers[2] = 30;
numbers[3] = 40;
numbers[4] = 50;

// 使用循环赋值
for (int i = 0; i < numbers.length; i++) {
    numbers[i] = (i + 1) * 10;
}

数组访问和操作

访问数组元素

基本访问:
int[] numbers = {10, 20, 30, 40, 50};

// 访问元素(索引从0开始)
int first = numbers[0];    // 获取第一个元素:10
int third = numbers[2];    // 获取第三个元素:30
int last = numbers[4];     // 获取最后一个元素:50

// 修改元素
numbers[1] = 25;           // 将第二个元素改为25
numbers[3] = 45;           // 将第四个元素改为45

// 获取数组长度
int length = numbers.length;  // 数组长度:5

遍历数组

遍历方法:
int[] numbers = {10, 20, 30, 40, 50};

// 方式1:传统for循环
for (int i = 0; i < numbers.length; i++) {
    System.out.println("索引 " + i + ": " + numbers[i]);
}

// 方式2:增强for循环(for-each)
for (int num : numbers) {
    System.out.println("元素值: " + num);
}

// 方式3:while循环
int i = 0;
while (i < numbers.length) {
    System.out.println("元素 " + i + ": " + numbers[i]);
    i++;
}

数组越界异常

访问数组时要注意索引范围,有效索引为 0 到 length-1。超出范围会抛出 ArrayIndexOutOfBoundsException 异常。

int[] arr = new int[5];  // 有效索引:0, 1, 2, 3, 4
int value = arr[5];      // 错误!会抛出异常
int value = arr[-1];     // 错误!会抛出异常

数组内存模型

数组在内存中的存储

理解数组的内存模型有助于更好地使用数组:

栈内存

存储数组变量

arr

堆内存

存储数组对象

[10][20][30]
内存分配示例:
int[] arr = new int[]{10, 20, 30};

// 栈内存:变量arr存储数组对象的地址
// 堆内存:实际的数组对象存储在堆中
// arr[0] → 堆中第一个位置的值 10
// arr[1] → 堆中第二个位置的值 20
// arr[2] → 堆中第三个位置的值 30

完整代码示例

ArrayBasicsExample.java
/**
 * Java数组基础示例
 * 演示数组的声明、创建、初始化和基本操作
 */
public class ArrayBasicsExample {
    
    public static void main(String[] args) {
        // 1. 数组声明和创建
        System.out.println("=== 数组声明和创建 ===");
        int[] numbers = new int[5];  // 创建长度为5的整型数组
        System.out.println("数组长度: " + numbers.length);
        
        // 2. 数组初始化
        System.out.println("\n=== 数组初始化 ===");
        // 静态初始化
        int[] scores = {85, 92, 78, 96, 88};
        String[] names = {"张三", "李四", "王五", "赵六", "钱七"};
        
        // 动态初始化
        for (int i = 0; i < numbers.length; i++) {
            numbers[i] = (i + 1) * 10;
        }
        
        // 3. 数组访问和遍历
        System.out.println("\n=== 数组遍历 ===");
        System.out.println("学生成绩信息:");
        for (int i = 0; i < names.length; i++) {
            System.out.println(names[i] + ": " + scores[i] + "分");
        }
        
        // 4. 使用增强for循环
        System.out.println("\n=== 增强for循环 ===");
        System.out.print("numbers数组: ");
        for (int num : numbers) {
            System.out.print(num + " ");
        }
        System.out.println();
        
        // 5. 数组统计操作
        System.out.println("\n=== 数组统计 ===");
        int sum = 0;
        int max = scores[0];
        int min = scores[0];
        
        for (int score : scores) {
            sum += score;
            if (score > max) max = score;
            if (score < min) min = score;
        }
        
        double average = (double) sum / scores.length;
        System.out.println("总分: " + sum);
        System.out.println("平均分: " + String.format("%.2f", average));
        System.out.println("最高分: " + max);
        System.out.println("最低分: " + min);
        
        // 6. 数组查找
        System.out.println("\n=== 数组查找 ===");
        int target = 92;
        int index = findElement(scores, target);
        if (index != -1) {
            System.out.println("找到元素 " + target + ",位置: " + index);
        } else {
            System.out.println("未找到元素 " + target);
        }
    }
    
    /**
     * 在数组中查找指定元素
     * @param arr 要搜索的数组
     * @param target 目标元素
     * @return 元素的索引,如果未找到返回-1
     */
    public static int findElement(int[] arr, int target) {
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == target) {
                return i;
            }
        }
        return -1;
    }
}
💻 查看完整代码 - 在线IDE体验

数组使用最佳实践

编程建议

推荐做法

  • 使用 数据类型[] 数组名 的声明方式
  • 访问数组前检查索引范围
  • 使用 array.length 获取数组长度
  • 优先使用增强for循环遍历
  • 给数组变量起有意义的名字
  • 合理估算数组大小避免浪费

避免做法

  • 不检查数组边界直接访问
  • 使用魔法数字作为数组长度
  • 在循环中重复计算 array.length
  • 忽略数组的默认初始化值
  • 混用不同的数组声明语法
  • 创建过大的数组造成内存浪费

本章总结