JAVA基础——数组与二维数组
JAVA基础——数组与二维数组
一、数组概述
1.1 数组的定义与作用
- 定义:数组是用于存储同一类型数据的有序数据容器。
- 作用:解决批量数据存储问题,避免使用大量独立变量,提升数据处理效率。
- 核心特性:
- 元素类型统一(如
int[]
、String[]
)。 - 长度固定(创建后不可改变)。
- 元素通过**索引(下标)**访问,索引从
0
开始。
- 元素类型统一(如
1.2 数组的初始化方式
1.2.1 静态初始化
- 定义时指定元素值,适用于已知数据的场景。
- 格式:
数据类型[] 数组名 = {元素1, 元素2, 元素3, ...}; // 简化格式 数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, 元素3, ...}; // 完整格式
- 示例:
int[] scores = {85, 90, 95}; // 存储3门课成绩 String[] names = new String[]{"张三", "李四", "王五"}; // 存储学生姓名
1.2.2 动态初始化
- 定义时指定数组长度,元素初始值由系统自动填充。
- 格式:
数据类型[] 数组名 = new 数据类型[长度];
- 默认值规则:
数据类型 默认值 示例 整数类型(byte/short/int/long) 0
int[] arr = new int[3];
→[0, 0, 0]
浮点类型(float/double) 0.0
double[] arr = new double[2];
→[0.0, 0.0]
字符型(char) \u0000
(空字符)char[] arr = new char[2];
→['\u0000', '\u0000']
布尔型(boolean) false
boolean[] arr = new boolean[2];
→[false, false]
引用类型(如String) null
String[] arr = new String[2];
→[null, null]
1.3 数组的访问与遍历
1.3.1 访问元素
- 语法:
数组名[索引]
,索引范围:0
~数组长度-1
。 - 示例:
int[] arr = {12, 24, 36}; System.out.println(arr[0]); // 输出:12(第一个元素) arr[1] = 100; // 修改第二个元素为100
1.3.2 获取数组长度
- 属性:
数组名.length
,返回数组元素个数(int类型)。 - 示例:
int[] arr = {1, 2, 3, 4, 5}; int len = arr.length; // len = 5
1.3.3 遍历数组
- 定义:逐个访问数组中的每个元素。
- 实现方式:
- for循环遍历:
int[] scores = {85, 90, 95}; for (int i = 0; i < scores.length; i++) {System.out.println("索引 " + i + " 的值:" + scores[i]); }
- 增强for循环(JDK5+):适用于简单遍历(无法获取索引)。
for (int score : scores) { // 依次将scores中的元素赋值给score变量System.out.println("成绩:" + score); }
- for循环遍历:
1.4 数组综合案例:学生成绩统计
案例需求
- 录入8名学生的Java成绩(小数类型),计算并输出平均分、最高分、最低分。
实现思路
- 动态初始化数组:
double[] scores = new double[8];
- 录入成绩:使用
Scanner
获取用户输入。 - 遍历数组:计算总和、最大值、最小值。
- 计算结果:平均分=总和/人数,注意数据类型转换。
代码示例
import java.util.Scanner;public class ScoreStatistics {public static void main(String[] args) {Scanner sc = new Scanner(System.in);double[] scores = new double[8]; // 动态初始化数组// 录入成绩for (int i = 0; i < scores.length; i++) {System.out.print("请输入第" + (i+1) + "名学生的成绩:");scores[i] = sc.nextDouble();}// 计算总和、最高分、最低分double sum = 0, max = scores[0], min = scores[0];for (int i = 1; i < scores.length; i++) {sum += scores[i];if (scores[i] > max) {max = scores[i];}if (scores[i] < min) {min = scores[i];}}// 输出结果double avg = sum / scores.length;System.out.println("平均分:" + avg);System.out.println("最高分:" + max);System.out.println("最低分:" + min);}
}
二、数组的高级操作
2.1 数组元素交换
- 场景:洗牌、排序等需要重新排列元素顺序的操作。
- 实现方法:通过临时变量交换两个索引位置的元素。
- 示例:交换数组
arr
中索引i
和j
的元素:int[] arr = {10, 20, 30, 40}; int i = 0, j = 3; int temp = arr[i]; // 临时存储arr[i] arr[i] = arr[j]; // 将arr[j]赋值给arr[i] arr[j] = temp; // 将临时值赋值给arr[j] // 结果:arr = {40, 20, 30, 10}
2.2 数组应用:简易斗地主游戏(做牌与洗牌)
2.2.1 做牌(静态初始化)
- 牌面构成:52张普通牌(4种花色×13张点数)+ 2张王。
- 代码实现:
String[] suits = {"♠", "♥", "♣", "♦"}; // 花色 String[] ranks = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"}; // 点数 String[] poker = new String[54]; // 54张牌的数组// 生成普通牌(52张) int index = 0; for (String suit : suits) {for (String rank : ranks) {poker[index++] = suit + rank; // 拼接花色和点数} } // 添加大小王 poker[52] = "小王"; poker[53] = "大王";
2.2.2 洗牌(随机交换元素)
- 原理:从数组中随机选取元素,与当前元素交换位置。
- 代码实现:
import java.util.Random;Random r = new Random(); for (int i = 0; i < poker.length; i++) {int randomIndex = r.nextInt(poker.length); // 生成0-53的随机索引// 交换i和randomIndex位置的元素String temp = poker[i];poker[i] = poker[randomIndex];poker[randomIndex] = temp; }
三、二维数组
3.1 二维数组的定义
-
本质:数组中的每个元素又是一个一维数组,用于存储二维表格数据(如座位表、矩阵)。
-
初始化方式:
3.1.1 静态初始化
// 完整格式 数据类型[][] 数组名 = new 数据类型[][]{{元素行1}, {元素行2}, {元素行3}, ...}; // 简化格式 数据类型[][] 数组名 = {{元素行1}, {元素行2}, {元素行3}, ...};
示例:存储班级座位表(4行,每行人数不同):
String[][] seats = {{"张无忌", "赵敏", "周芷若"}, // 第1行(索引0){"张三丰", "宋远桥", "殷梨亭"}, // 第2行(索引1){"灭绝", "陈昆", "玄冥二老", "金毛狮王"}, // 第3行(索引2){"杨逍", "纪晓芙"} // 第4行(索引3) };
3.1.2 动态初始化
// 指定行数和列数(每行列数相同) 数据类型[][] 数组名 = new 数据类型[行数][列数]; // 仅指定行数(每行列数可不同,类似“锯齿数组”) 数据类型[][] 数组名 = new 数据类型[行数][];
示例:
int[][] arr = new int[3][5]; // 3行5列,所有元素初始化为0 double[][] scores = new double[2][]; // 2行,每行列数后续指定 scores[0] = new double[3]; // 第1行3列 scores[1] = new double[2]; // 第2行2列
3.2 二维数组的访问与遍历
3.2.1 访问元素
- 语法:
数组名[行索引][列索引]
- 示例:
String[][] seats = {{"A", "B"}, {"C", "D", "E"}}; System.out.println(seats[0][1]); // 输出:B(第1行第2列) seats[1][2] = "F"; // 修改第2行第3列为F
3.2.2 获取维度长度
- 行数:
数组名.length
- 某一行的列数:
数组名[行索引].length
- 示例:
int rows = seats.length; // 行数:2 int cols = seats[0].length; // 第1行的列数:2
3.2.3 遍历二维数组
- 双重for循环:外层循环遍历行,内层循环遍历列。
输出结果:for (int i = 0; i < seats.length; i++) { // 遍历行(i为行索引)System.out.print("第" + (i+1) + "排:");for (int j = 0; j < seats[i].length; j++) { // 遍历列(j为列索引)System.out.print(seats[i][j] + "\t");}System.out.println(); // 换行 }
第1排:A B 第2排:C D E
四、常见问题与注意事项
4.1 数组越界异常(ArrayIndexOutOfBoundsException)
- 原因:访问索引超出数组范围(如
arr[-1]
或arr[arr.length]
)。 - 解决:确保索引在
0
~arr.length-1
范围内,遍历数组时用length
属性控制循环条件。
4.2 空指针异常(NullPointerException)
- 原因:引用类型数组元素未初始化(值为
null
)时访问其属性或方法。 - 示例:
String[] names = new String[2]; // 元素默认值为null System.out.println(names[0].length()); // 报错!names[0]为null,无法调用length()
- 解决:初始化引用类型数组元素后再使用:
names[0] = "张三"; // 赋值后再访问
4.3 数组与变量的区别
对比维度 | 变量 | 数组 |
---|---|---|
存储数据量 | 单个值 | 多个同类型值 |
数据类型 | 基本类型或引用类型 | 仅引用类型(存储基本类型的数组也是引用类型) |
内存分配 | 栈内存或堆内存 | 堆内存 |
访问方式 | 直接通过变量名 | 通过索引 |
五、总结
5.1 核心知识点速查表
知识点 | 关键内容 |
---|---|
数组定义 | 静态初始化(指定元素)、动态初始化(指定长度) |
数组访问 | 索引从0开始,数组名[索引] ,长度属性length |
数组遍历 | for循环、增强for循环 |
二维数组 | 数组的数组,双重for循环遍历,arr[row][col] |
常见异常 | 越界异常(IndexOutOfBounds)、空指针异常(NullPointerException) |
5.2 学习建议
- 多练习:通过案例(如成绩统计、洗牌算法)加深对数组操作的理解。
- 理解内存模型:数组是引用类型,变量存储数组对象的地址,而非元素本身。
- 拓展学习:后续可学习数组工具类(
Arrays
)的常用方法(如排序、查找)。