Java数组与二维数组入门核心语法
一、一维数组的核心定义与初始化
1.1 数组的本质
数组是Java中用于存储一批同类型数据的线性容器,核心特性如下:
- 容器内所有元素的数据类型必须完全一致;
- 数组在内存中占用连续的存储空间;
- 元素通过索引(下标)访问,索引从0开始计数;
- 数组长度一旦初始化,不可动态修改。
使用数组存储批量数据,相比独立变量具备显著优势:
- 代码结构简洁,避免定义大量冗余变量;
- 支持批量遍历与统一处理,大幅提升数据处理效率;
- 内存连续分配,数据访问性能稳定可控。
1.2 数组的两种初始化方式
Java数组提供静态初始化与动态初始化两种方式,分别适配不同的业务场景。
1.2.1 静态初始化
静态初始化适用于数组元素在定义时已完全明确的场景,定义时直接指定具体元素值,数组长度由元素个数自动确定。
标准语法:
// 简化格式(开发中主流写法)
数据类型[] 数组名 = {元素1, 元素2, 元素3, ...};
// 完整格式
数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, 元素3, ...};代码示例:
// 简化格式:存储3个int类型整数
int[] arr1 = {12, 24, 36};
// 完整格式:存储学生姓名列表
String[] names = new String[]{"张三", "李四", "王五", "赵六"};注意事项:
- 标准写法为
数据类型[] 数组名,虽支持数据类型 数组名[]的写法,但易造成语义混淆; - 静态初始化时禁止在
[]中指定数组长度,例如int[] arr = new int[3]{12,24,36};为非法语法,会编译报错。
1.2.2 动态初始化
动态初始化适用于数组元素在定义时未明确,需先确定容器长度,后续再赋值的场景,定义时仅指定数据类型与数组长度,元素采用Java默认值初始化。
标准语法:
数据类型[] 数组名 = new 数据类型[数组长度];代码示例:
// 动态初始化长度为3的int数组,元素默认值为0
int[] arr = new int[3];
// 动态初始化长度为8的double数组,用于存储学生成绩,元素默认值为0.0
double[] scores = new double[8];动态初始化的元素默认值规则,由数组的数据类型决定,具体如下表:
| 数据类型分类 | 具体数据类型 | 默认初始值 |
|---|---|---|
| 基本数据类型 | byte、short、char、int、long | 0 |
| 基本数据类型 | float、double | 0.0 |
| 基本数据类型 | boolean | false |
| 引用数据类型 | 类、接口、数组、String | null |
1.3 数组的元素访问与核心属性
数组元素通过数组名[索引] 的格式访问,支持元素的读取与修改;数组提供length属性,用于获取数组的元素个数(长度)。
核心语法:
// 1. 读取元素
元素类型 变量名 = 数组名[索引];
// 2. 修改元素
数组名[索引] = 新值;
// 3. 获取数组长度
int 长度变量 = 数组名.length;代码示例:
public class ArrayAccessDemo {
public static void main(String[] args) {
int[] arr = {12, 24, 36};
// 读取索引0的元素
System.out.println(arr[0]); // 输出:12
// 修改索引1的元素值
arr[1] = 100;
System.out.println(arr[1]); // 输出:100
// 获取数组长度
System.out.println(arr.length); // 输出:3
}
}注意事项:数组的合法索引范围为0 ~ 数组长度-1,若访问超出该范围的索引,会抛出ArrayIndexOutOfBoundsException(数组索引越界异常),是数组操作中最常见的运行时异常。
二、数组的核心遍历操作与经典场景实现
2.1 数组的遍历
数组遍历指依次访问数组中的每一个元素,是数组所有批量操作的基础,广泛应用于数据求和、最值查找、元素筛选、批量赋值等场景。
Java中最基础的遍历方式为for循环遍历,语法如下:
int[] arr = {20, 30, 40, 50};
// 遍历数组:i为索引,从0开始,到数组长度-1结束
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}2.2 经典场景1:数组元素求最值
业务需求:获取数组中元素的最大值、最小值,是业务开发中数据统计的基础能力。
实现思路:
- 定义变量存储当前最值,初始值赋值为数组第一个元素;
- 遍历数组,将每个元素与当前最值比较,若符合条件则更新最值变量;
- 遍历结束后,最值变量即为数组的最终结果。
代码实现:
public class ArrayMaxMinDemo {
public static void main(String[] args) {
int[] faceScores = {15, 9000, 10000, 20000, 9500, -5};
// 初始化最值为数组第一个元素
int max = faceScores[0];
int min = faceScores[0];
// 遍历数组更新最值
for (int i = 1; i < faceScores.length; i++) {
if (faceScores[i] > max) {
max = faceScores[i];
}
if (faceScores[i] < min) {
min = faceScores[i];
}
}
// 输出结果
System.out.println("数组最大值:" + max); // 输出:20000
System.out.println("数组最小值:" + min); // 输出:-5
}
}2.3 经典场景2:学生成绩统计
业务需求:录入班级8名学生的Java课程成绩,计算并输出班级成绩的平均分、最高分、最低分。
代码实现:
import java.util.Scanner;
public class ScoreStatisticsDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 动态初始化数组,存储8名学生的成绩
double[] scores = new double[8];
// 循环录入学生成绩
for (int i = 0; i < scores.length; i++) {
System.out.println("请输入第" + (i+1) + "名学生的Java成绩:");
scores[i] = scanner.nextDouble();
}
scanner.close();
// 初始化统计变量
double sum = 0.0;
double max = scores[0];
double min = scores[0];
// 遍历数组完成统计
for (double score : scores) {
sum += score;
if (score > max) max = score;
if (score < min) min = score;
}
// 计算平均分
double average = sum / scores.length;
// 输出统计结果
System.out.println("班级成绩最高分:" + max);
System.out.println("班级成绩最低分:" + min);
System.out.println("班级成绩总分:" + sum);
System.out.println("班级成绩平均分:" + average);
}
}2.4 数组元素交换
数组元素交换是排序算法、数组乱序(洗牌)的基础操作,核心实现思路是通过临时变量中转两个元素的值,完成交换。
代码实现:
public class ArraySwapDemo {
public static void main(String[] args) {
int[] arr = {10, 20, 30, 40, 50};
// 交换索引0和索引4的元素
int temp = arr[0]; // 临时变量存储第一个元素的值
arr[0] = arr[4]; // 将最后一个元素赋值给第一个位置
arr[4] = temp; // 将临时变量的值赋值给最后一个位置
// 遍历输出交换后的数组:50 20 30 40 10
for (int num : arr) {
System.out.print(num + " ");
}
}
}三、数组的工程化实践案例
3.1 案例1:随机点名系统
业务需求:开发班级随机点名程序,从学生名单中随机抽取一名学生,实现课堂随机点名场景。
代码实现:
import java.util.Random;
public class RandomCallNameDemo {
public static void main(String[] args) {
// 数组存储班级学生姓名
String[] names = {
"张誉", "刘疏桐", "田启峰", "伊成元", "赵志刚",
"解天野", "高续升", "王世举", "周字伦", "刘帅",
"陈小伟", "陈伟北", "高明", "毕振宇", "王乾麟"
};
// 生成随机索引:范围 0 ~ names.length-1
Random random = new Random();
int randomIndex = random.nextInt(names.length);
// 获取随机抽取的学生姓名
String selectedName = names[randomIndex];
// 输出点名结果
System.out.println(selectedName + "同学,出来回答问题!");
}
}3.2 案例2:斗地主游戏-卡牌初始化与洗牌
业务需求:开发简易版斗地主游戏的核心基础能力,完成54张卡牌的初始化(做牌)与洗牌功能。
实现思路:
- 定义两个数组,分别存储卡牌的花色与点数;
- 动态初始化长度为54的String数组,存储所有卡牌;
- 嵌套循环组合花色与点数,完成52张普通卡牌初始化,单独添加大小王;
- 洗牌功能:遍历数组,随机生成索引,交换当前元素与随机索引的元素,完成数组乱序。
代码实现:
import java.util.Random;
public class LandlordCardDemo {
public static void main(String[] args) {
// 1. 定义卡牌的花色与点数
String[] colors = {"♠", "♥", "♣", "♦"};
String[] numbers = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
// 2. 动态初始化数组,存储54张卡牌
String[] cards = new String[54];
int index = 0; // 卡牌数组的索引
// 3. 组合花色与点数,初始化普通卡牌
for (String number : numbers) {
for (String color : colors) {
cards[index] = color + number;
index++;
}
}
// 4. 添加大小王
cards[index++] = "小王";
cards[index] = "大王";
// 输出初始化完成的卡牌
System.out.println("初始化完成的卡牌:");
for (String card : cards) {
System.out.print(card + " ");
}
System.out.println("\n");
// 5. 洗牌:数组乱序
Random random = new Random();
for (int i = 0; i < cards.length; i++) {
int randomIndex = random.nextInt(cards.length);
// 元素交换
String temp = cards[i];
cards[i] = cards[randomIndex];
cards[randomIndex] = temp;
}
// 输出洗牌后的卡牌
System.out.println("洗牌后的卡牌:");
for (String card : cards) {
System.out.print(card + " ");
}
}
}四、二维数组的核心定义与实践
4.1 二维数组的本质
二维数组是数组的数组,即数组中的每一个元素,都是一个独立的一维数组。二维数组适用于存储具有行、列二维结构的业务数据,如班级座位信息、表格数据、矩阵运算、2D游戏地图等场景。
4.2 二维数组的初始化方式
4.2.1 静态初始化
静态初始化适用于二维数组的行、列数据在定义时已明确的场景,直接指定每一行的一维数组元素。
标准语法:
// 简化格式
数据类型[][] 数组名 = {{元素1,元素2...}, {元素1,元素2...}, ...};
// 完整格式
数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2...}, {元素1,元素2...}, ...};代码示例:存储班级座位信息
// 二维数组存储班级座位,每一行对应一排座位
String[][] seats = {
{"张无忌", "赵敏", "周芷若"},
{"张三丰", "宋远桥", "殷梨亭"},
{"灭绝", "陈昆", "玄冥二老", "金毛狮王"},
{"杨逍", "纪晓芙"}
};4.2.2 动态初始化
动态初始化分为两种模式,适配不同的业务场景:
固定列数初始化:每一行的列数完全一致,适用于规则的表格、矩阵场景
// 3行5列的二维数组 数据类型[][] 数组名 = new 数据类型[行数][列数];不规则列数初始化:先指定行数,后续为每一行单独定义列数,适用于行列数不统一的不规则场景
// 先指定4行,列数后续定义 数据类型[][] 数组名 = new 数据类型[行数][]; // 为每一行初始化一维数组 数组名[0] = new 数据类型[3]; 数组名[1] = new 数据类型[4];
代码示例:
// 固定列数:3行5列的int二维数组,初始默认值为0
int[][] arr1 = new int[3][5];
// 不规则列数:4行的二维数组,每行列数不同
String[][] seats = new String[4][];
seats[0] = new String[3]; // 第一排3个座位
seats[1] = new String[3]; // 第二排3个座位
seats[2] = new String[4]; // 第三排4个座位
seats[3] = new String[2]; // 第四排2个座位4.3 二维数组的元素访问
二维数组的元素通过行索引与列索引进行访问,语法如下:
// 访问某一行的一维数组:数组名[行索引]
// 访问具体元素:数组名[行索引][列索引]
// 修改元素值:数组名[行索引][列索引] = 新值;代码示例:
public class TwoDArrayAccessDemo {
public static void main(String[] args) {
int[][] arr = new int[][]{{12, 24, 36}, {666, 888}, {10, 20, 30}, {999}};
// 访问第3行(索引2)的一维数组
int[] row = arr[2];
// 遍历输出该行元素:10 20 30
for (int num : row) {
System.out.print(num + " ");
}
System.out.println();
// 访问第3行第2列(索引2、1)的元素
System.out.println(arr[2][1]); // 输出:20
// 修改第4行第1列(索引3、0)的元素
arr[3][0] = 111;
System.out.println(arr[3][0]); // 输出:111
}
}4.4 二维数组的遍历
二维数组的遍历需要使用嵌套循环,外层循环遍历每一行,内层循环遍历当前行的每一列元素。
标准语法:
int[][] arr = {{12, 24, 36}, {666, 888}, {10, 20, 30}, {999}};
// 外层循环:遍历每一行
for (int i = 0; i < arr.length; i++) {
// 内层循环:遍历当前行的每一列
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + "\t");
}
// 每行遍历完成后换行
System.out.println();
}4.5 实践案例:班级座位信息管理
业务需求:存储并输出班级的座位信息,要求输出时直观展示学生所在的排数与座位号。
代码实现:
public class SeatManagerDemo {
public static void main(String[] args) {
// 二维数组存储班级座位信息
String[][] seats = {
{"张无忌", "赵敏", "周芷若"},
{"张三丰", "宋远桥", "殷梨亭"},
{"灭绝", "陈昆", "玄冥二老", "金毛狮王"},
{"杨逍", "纪晓芙"}
};
// 遍历输出座位信息
System.out.println("===== 班级座位信息 =====");
for (int i = 0; i < seats.length; i++) {
System.out.print("第" + (i+1) + "排:");
for (int j = 0; j < seats[i].length; j++) {
System.out.print(seats[i][j] + " ");
}
System.out.println();
}
}
}执行结果:
===== 班级座位信息 =====
第1排:张无忌 赵敏 周芷若
第2排:张三丰 宋远桥 殷梨亭
第3排:灭绝 陈昆 玄冥二老 金毛狮王
第4排:杨逍 纪晓芙 4.6 拓展场景:2D游戏地图初始化
二维数组广泛应用于2D游戏的地图数据存储,例如石头迷阵、推箱子、贪吃蛇等游戏,均可通过二维数组存储地图格子数据,实现地图的初始化与渲染。
示例代码:石头迷阵地图初始化
public class StoneMazeDemo {
public static void main(String[] args) {
// 4行4列的二维数组,存储16格石头迷阵的数字
int[][] maze = new int[4][4];
int num = 1;
// 初始化地图数字 1-15,最后一格为0(代表空位)
for (int i = 0; i < maze.length; i++) {
for (int j = 0; j < maze[i].length; j++) {
maze[i][j] = num <= 15 ? num++ : 0;
}
}
// 输出初始化的迷阵地图
System.out.println("===== 石头迷阵初始地图 =====");
for (int[] row : maze) {
for (int data : row) {
// 空位显示为空格,数字格式化输出
System.out.print(data == 0 ? " \t" : data + "\t");
}
System.out.println();
}
}
}