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 
相关推荐
roman_日积跬步-终至千里1 分钟前
【人工智能导论】02-搜索-高级搜索策略探索篇:从约束满足到博弈搜索
java·前端·人工智能
大学生资源网28 分钟前
java毕业设计之儿童福利院管理系统的设计与实现(源码+)
java·开发语言·spring boot·mysql·毕业设计·源码·课程设计
JasmineWr28 分钟前
JVM栈空间的使用和优化
java·开发语言
Hello.Reader33 分钟前
Flink SQL DELETE 语句批模式行级删除、连接器能力要求与实战避坑(含 Java 示例)
java·sql·flink
爱笑的眼睛1137 分钟前
从 Seq2Seq 到 Transformer++:深度解构与自构建现代机器翻译核心组件
java·人工智能·python·ai
Spring AI学习44 分钟前
Spring AI深度解析(10/50):多模态应用开发实战
java·spring·ai
qq_12498707533 小时前
重庆三峡学院图书资料管理系统设计与实现(源码+论文+部署+安装)
java·spring boot·后端·mysql·spring·毕业设计
大学生资源网3 小时前
java毕业设计之“知语”花卉销售网站的设计与实现源码(源代码+文档)
java·mysql·毕业设计·源码·springboot
小鸡脚来咯4 小时前
Redis三大问题:穿透、击穿、雪崩(实战解析)
java·spring·mybatis
桦说编程4 小时前
并发编程高级技巧:运行时检测死锁,告别死锁焦虑
java·后端·性能优化