Java 数组详解

数组是 Java 中最基础的数据结构之一,用于存储相同类型的多个元素,具有固定长度、连续内存分配的特点,是处理批量数据的核心工具。本文将从数组的定义、初始化、访问、遍历、常用操作到进阶应用,结合实战代码全面解析 Java 数组的使用,帮你夯实基础、灵活运用。

一、数组核心概念

1. 定义

数组是一种引用数据类型,它将多个相同类型的元素按顺序存储在连续的内存空间中,通过 "数组名 + 索引" 快速访问元素。

2. 核心特性

  • 固定长度:数组一旦创建,长度不可修改(长度由初始化时指定);
  • 相同类型:所有元素必须是同一数据类型(如 int、String、自定义类);
  • 索引访问 :索引从0开始,最大索引为数组长度-1(超出索引会抛ArrayIndexOutOfBoundsException);
  • 内存特性:数组对象存储在堆内存,数组名(引用)存储在栈内存。

3. 数组的分类

  • 按维度:一维数组(常用)、二维数组(矩阵结构)、多维数组(极少用);
  • 按元素类型:基本类型数组(int \[\]、double \[\])、引用类型数组(String \[\]、Object \[\])。

二、一维数组的使用(重点)

1. 数组的声明

声明数组有两种语法格式(推荐第一种,更清晰):

java 复制代码
// 格式1(推荐):数据类型[] 数组名;
int[] scores; // 声明一个int类型的数组,变量名为scores
String[] names; // 声明一个String类型的数组

// 格式2:数据类型 数组名[];(兼容C/C++语法,不推荐)
int ages[];

注意 :声明时仅定义数组引用,未分配内存,数组名此时为null

2. 数组的初始化

数组必须初始化后才能使用,初始化的核心是分配内存空间赋值(默认值或自定义值)。分为三种方式:

(1)静态初始化(已知元素值)

直接指定每个元素的值,数组长度由元素个数自动推导:

java 复制代码
// 语法:数据类型[] 数组名 = {元素1, 元素2, ..., 元素n};
int[] scores = {90, 85, 95, 78, 88}; // 长度为5的int数组
String[] names = {"张三", "李四", "王五"}; // 长度为3的String数组

// 完整写法(显式指定new关键字,适合声明和赋值分离场景)
int[] ages = new int[]{20, 21, 22};

注意 :静态初始化不能同时指定长度和元素值(如int[] arr = new int[3]{1,2,3}会编译报错)。

(2)动态初始化(已知长度,未知元素值)

指定数组长度,系统自动为元素分配默认值,后续可手动修改:

java 复制代码
// 语法:数据类型[] 数组名 = new 数据类型[数组长度];
int[] nums = new int[5]; // 长度为5的int数组,默认值为0
double[] prices = new double[3]; // 长度为3的double数组,默认值为0.0
boolean[] flags = new boolean[4]; // 长度为4的boolean数组,默认值为false
String[] address = new String[2]; // 长度为2的String数组,默认值为null

基本类型默认值表

数据类型 默认值
byte/short/int/long 0
float/double 0.0
boolean false
char '\u0000'(空字符)
引用类型(String/Object 等) null

(3)默认初始化(仅声明 + 分配内存)

仅声明数组并分配内存,元素使用系统默认值(同动态初始化):

java 复制代码
int[] arr = new int[4];
System.out.println(arr[0]); // 输出:0(int默认值)

3. 数组的访问与修改

通过 "数组名 索引" 访问或修改元素,索引范围是0 ~ 数组长度-1

java 复制代码
public class ArrayAccess {
    public static void main(String[] args) {
        int[] scores = {90, 85, 95, 78};
        
        // 访问元素(索引0对应第一个元素)
        System.out.println("第一个元素:" + scores[0]); // 输出:90
        System.out.println("最后一个元素:" + scores[scores.length - 1]); // 输出:78(length属性获取长度)
        
        // 修改元素
        scores[2] = 100; // 将索引2的元素(原95)改为100
        System.out.println("修改后第三个元素:" + scores[2]); // 输出:100
        
        // 错误示例:索引越界(编译通过,运行时抛异常)
        // System.out.println(scores[4]); // 报错:ArrayIndexOutOfBoundsException
    }
}

关键数组名.length获取数组长度(只读属性,不能修改)。

4. 数组的遍历(核心操作)

遍历是指依次访问数组的每个元素,常用两种方式:for循环(适合需要索引的场景)和for-each循环(适合仅遍历元素的场景)。

(1)普通 for 循环(带索引)

java 复制代码
public class ArrayForLoop {
    public static void main(String[] args) {
        String[] fruits = {"苹果", "香蕉", "橙子", "葡萄"};
        
        // 普通for循环:通过索引遍历
        for (int i = 0; i < fruits.length; i++) {
            System.out.println("索引" + i + ":" + fruits[i]);
        }
    }
}

输出结果

plaintext

索引0:苹果

索引1:香蕉

索引2:橙子

索引3:葡萄

(2)for-each 循环(增强 for 循环,无索引)

语法简洁,无需关注索引,仅遍历元素值(无法修改元素本身,适合读取):

java 复制代码
public class ArrayForEach {
    public static void main(String[] args) {
        int[] nums = {10, 20, 30, 40};
        
        // for-each循环:for (元素类型 变量名 : 数组名)
        for (int num : nums) {
            System.out.println("元素值:" + num);
        }
    }
}

输出结果

plaintext

元素值:10

元素值:20

元素值:30

元素值:40

(3)Java 8+ Stream 遍历(进阶)

结合 Stream API 实现更灵活的遍历(如过滤、排序):

java 复制代码
import java.util.Arrays;

public class ArrayStream {
    public static void main(String[] args) {
        int[] scores = {85, 92, 78, 95, 88};
        
        // Stream遍历:过滤出大于90的分数并打印
        Arrays.stream(scores)
              .filter(score -> score > 90)
              .forEach(score -> System.out.println("高分:" + score));
    }
}

输出结果

plaintext

高分:92

高分:95

三、二维数组(矩阵结构)

二维数组本质是 "数组的数组",即每个元素都是一个一维数组,适用于存储表格、矩阵等结构化数据。

1. 声明与初始化

(1)静态初始化(已知所有元素)

java 复制代码
// 格式1:数据类型[][] 数组名 = {{元素1,元素2}, {元素3,元素4}, ...};
int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; // 3行3列的矩阵

// 格式2:显式指定new关键字
String[][] students = new String[][]{{"张三", "男"}, {"李四", "女"}};

(2)动态初始化(已知行数和列数)

java 复制代码
// 格式1:指定行数和列数(每行列数相同,规则矩阵)
int[][] arr1 = new int[2][3]; // 2行3列,元素默认值为0

// 格式2:仅指定行数,列数动态分配(每行列数可不同,不规则矩阵)
int[][] arr2 = new int[3][]; // 3行,列数未指定
arr2[0] = new int[2]; // 第1行2列
arr2[1] = new int[4]; // 第2行4列
arr2[2] = new int[3]; // 第3行3列

2. 访问与遍历

通过 "数组名 行索引列索引" 访问元素,遍历需嵌套循环:

java 复制代码
public class TwoDimensionalArray {
    public static void main(String[] args) {
        int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
        
        // 访问元素(第2行第3列,索引从0开始)
        System.out.println("matrix[1][2]:" + matrix[1][2]); // 输出:6
        
        // 遍历二维数组(嵌套for循环)
        System.out.println("二维数组遍历:");
        for (int i = 0; i < matrix.length; i++) { // 遍历行(matrix.length是行数)
            for (int j = 0; j < matrix[i].length; j++) { // 遍历列(matrix[i].length是第i行的列数)
                System.out.print(matrix[i][j] + " ");
            }
            System.out.println(); // 换行
        }
        
        // for-each遍历二维数组
        System.out.println("for-each遍历:");
        for (int[] row : matrix) { // 每行是一个int[]数组
            for (int num : row) { // 遍历每行的元素
                System.out.print(num + " ");
            }
            System.out.println();
        }
    }
}

输出结果

plaintext

css 复制代码
matrix[1][2]:6
二维数组遍历:
1 2 3 
4 5 6 
7 8 9 
for-each遍历:
1 2 3 
4 5 6 
7 8 9 
相关推荐
神明不懂浪漫3 分钟前
【第五章】Java中的继承与多态
java·开发语言
AI多Agent协作实战派2 小时前
AI多Agent协作系统实战(十七):凌晨4点,我的AI系统在“假装工作“——3个bug同时爆炸的5小时
java·前端·bug
gaolei_eit2 小时前
Java+Ai+vue
java·spring·maven
qq_2518364572 小时前
基于java Web 动漫视频网站毕业论文
java·开发语言·前端
LayZhangStrive2 小时前
JUC相关的函数、注解、变量杂记
java·面试·多线程·juc
未秃头的程序猿2 小时前
给公司做了个AI客服Agent,用的Spring AI 1.0,3天上线领导拍板了
java·后端·ai编程
曹牧3 小时前
Eclipse 批量文本替换
java·ide·eclipse
程序员清风3 小时前
OpenAI官方发布最新提示词技巧!
java·后端·面试
一只枫林3 小时前
MySQL内、外连接知识点汇总
java·前端·数据库
梅头脑3 小时前
写了3年CRUD,volatile和synchronized的区别还是答不清——直到我画出了这张三性两锁边界图
java