Java 数组
Java 数组
在程序开发中,经常需要处理大量同类型数据(如需要读取100位学员的学科成绩,计算平均成绩,然后找出成绩大于平均值的学生)。若为每个数据声明单独变量,会导致代码冗余、维护困难。数组作为一种高效的数据存储结构,可解决此类问题,它能存储固定长度、相同类型的有序数据集合,通过索引快速访问元素。
一维数组
数组的核心特性
- 元素类型统一:数组中所有元素必须是同一种数据类型(如
int、String),不存在混合类型存储。
特殊情况:因Java继承特性,若数组元素类型为父类(如Fruit),可存储其子类对象(如Apple、Banana),但本质仍属于“父类类型数组”,元素类型逻辑上唯一。 - 长度固定:数组一旦创建,长度不可修改(长度由初始化时确定)。
- 引用数据类型:数组变量本质是引用,存储的是数组在内存中的地址,而非数据本身。未初始化时,数组变量值为
null。
数组声明
声明数组时,需指定元素类型和数组引用变量名,不能指定长度(长度在初始化时确定)。
语法格式
// 推荐写法:元素类型[] 数组名
elementType[] arrayName;
// 不推荐写法:元素类型 数组名[](与C/C++风格兼容,可读性差)
elementType arrayName[];
示例
int[] scores; // 声明一个int类型数组,变量名为scores
String[] names; // 声明一个String类型数组,变量名为names
数组初始化
数组声明后仅定义了引用变量,需通过“初始化”分配内存空间并赋值,才能使用。初始化分为静态初始化和动态初始化两种方式。
静态初始化
初始化时明确指定每个元素的值,数组长度由元素个数自动确定(无需显式声明长度)。
两种语法形式
| 语法形式 | 说明 | 示例 |
|---|---|---|
| 完整形式 | 使用new elementType[]显式创建数组,括号内写元素值 |
int[] scores = new int[]{90, 85, 95, 88}; |
| 简化形式 | 省略new elementType[],直接用大括号包裹元素值(必须在一条语句中完成声明+初始化) |
int[] scores = {90, 85, 95, 88}; |
注意事项
简化形式不能拆分语句,以下写法错误:
int[] scores;
scores = {90, 85, 95, 88}; // 错误:拆分后无法使用简化初始化
动态初始化
初始化时仅指定数组长度,元素值由系统自动分配默认值,后续可通过代码手动修改。
语法格式
// 先声明,后初始化
arrayName = new elementType[length];
// 声明+初始化一步完成
elementType[] arrayName = new elementType[length];
系统默认值规则
数组元素的默认值由数据类型决定,具体如下:
| 数据类型分类 | 默认值 | 示例 |
|---|---|---|
| 数值型(byte/short/int/long/float/double) | 0(浮点型为0.0) | int[] arr = new int[3]; → 元素默认值:[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] |
示例
// 动态初始化一个长度为5的int数组,元素默认值为0
int[] prices = new int[5];
// 动态初始化一个长度为3的String数组,元素默认值为null
Object[] books = new String[3];
数组大小与默认值
- 获取数组长度:通过
数组名.length获取数组长度(长度是int类型,且不可修改)。
示例:int length = prices.length;(若prices长度为5,length值为5)。 - 默认值生效时机:动态初始化时,系统立即为数组元素分配默认值;静态初始化时,元素值由用户指定,不使用默认值。
数组元素的访问与操作
元素访问语法
通过“数组名[索引] ”访问元素,索引(下标)从0开始,最大值为数组长度-1(即arrayName.length - 1)。
示例
int[] prices = new int[5];
prices[0] = 100; // 给第1个元素赋值(索引0)
prices[4] = 200; // 给第5个元素赋值(索引4,最后一个元素)
int lastPrice = prices[4]; // 获取最后一个元素的值
警告:索引越界问题
若访问的索引超出0 ~ 数组长度-1范围,会抛出运行时异常ArrayIndexOutOfBoundsException。
例如:对长度为5的prices数组,访问prices[5]会报错。
数组的常见处理场景(附代码示例)
数组处理常结合for循环(或foreach循环),以下为典型场景的完整代码实现:
场景1:使用用户输入初始化数组:循环使用用户输入的数值初始化数组。
package com.method_array;
import java.util.Scanner;
/**
* @Author Jing61
*/
public class ArrayDemo {
public static void main(String[] args) {
double[] list = new double[10];
Scanner input = new Scanner(System.in);
System.out.println("请输入" + list.length + "个数字:");
for (int i = 0; i < list.length; i++) {
list[i] = input.nextDouble();
}
input.close();
}
}
场景2:使用随机数初始化数组
通过Math.random()生成[0,100)的随机数,赋值给数组元素:
package com.method_array;
/**
* @Author Jing61
*/
public class ArrayDemo {
public static void main(String[] args) {
double[] list = new double[10];
for (int i = 0; i < list.length; i++) {
list[i] = Math.random() * 100;
System.out.print(list[i] + " ");
}
}
}
场景3:显示数组元素
两种方式:手动循环拼接格式,或使用Arrays.toString()(需导入java.util.Arrays):
package com.method_array;
import java.util.Arrays;
/**
* @Author Jing61
*/
public class ArrayDemo {
public static void main(String[] args) {
double[] arr = new double[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = Math.random() * 100;
}
System.out.print("[");
for (int i = 0; i < arr.length; i++)
System.out.print(arr[i] + (i == arr.length - 1 ? "]\n" : ", "));
//第二种形式:使用Arrays工具类完成打印
System.out.println("=========================");
System.out.println(Arrays.toString(arr));
}
}
场景4:计算数组元素总和
package com.method_array;
/**
* @Author Jing61
*/
public class ArrayDemo {
public static void main(String[] args) {
double[] arr = new double[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = Math.random() * 100;
}
System.out.print("[");
for (int i = 0; i < arr.length; i++) System.out.print(arr[i] + (i == arr.length - 1 ? "]\n" : ", "));
double total = 0;
for (int i = 0; i < arr.length; i++) {
total += arr[i];
}
System.out.println("数组中所有元素的和为:" + total);
}
}
场景5:查找数组中的最大值,使用名为 max 的变量存储最大值。将 max 的值初始化为 list[0],为了找出数组 list 中的最大元素,将每个元素与 max 比较,如果该元素大于 max,则更新 max。
package com.method_array;
/**
* @Author Jing61
*/
public class ArrayDemo {
public static void main(String[] args) {
double[] arr = new double[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = Math.random() * 100;
}
double max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (max < arr[i]) max = arr[i];
}
System.out.print("[");
for (int i = 0; i < arr.length; i++) System.out.print(arr[i] + (i == arr.length - 1 ? "]\n" : ", "));
System.out.println("最大值为:" + max);
}
}
场景6:查找最大值的最小下标
package com.method_array;
/**
* @Author Jing61
*/
public class ArrayDemo {
public static void main(String[] args) {
double[] arr = new double[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = Math.random() * 100;
}
double max = arr[0];
int index = 0;
for (int i = 1; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
index = i;
}
}
System.out.print("[");
for (int i = 0; i < arr.length; i++) System.out.print(arr[i] + (i == arr.length - 1 ? "]\n" : ", "));
System.out.println("最大值为:" + max);
System.out.println("最大值下标为:" + index);
}
}
场景7:随机打乱数组(洗牌效果)
通过“随机生成索引,交换元素”实现打乱。为了完成这种功能,针对每个元素 list[i],随意产生一个下标 j,然后将 list[i] 和 list[j] 互换
package com.method_array;
/**
* @Author Jing61
*/
public class ArrayDemo {
public static void main(String[] args) {
double[] arr = new double[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = Math.random() * 100;
}
System.out.print("[");
for (int i = 0; i < arr.length; i++) System.out.print(arr[i] + (i == arr.length - 1 ? "]\n" : ", "));
for (int i = 0; i < arr.length; i++) {
int j = (int)(Math.random() * arr.length);
double temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
System.out.println("打乱顺序后:");
System.out.print("[");
for (int i = 0; i < arr.length; i++) System.out.print(arr[i] + (i == arr.length - 1 ? "]\n" : ", "));
}
}
场景8:元素向左移动指定位数
package com.method_array;
/**
* @Author Jing61
*/
public class ArrayDemo {
public static void main(String[] args) {
double[] arr = new double[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = Math.random() * 100;
}
System.out.print("[");
for (int i = 0; i < arr.length; i++) System.out.print(arr[i] + (i == arr.length - 1 ? "]\n" : ", "));
int moveNumber = 1;// 移动的位数
double[] newArr = new double[arr.length];
for (int i = 0; i < arr.length; i++) {
newArr[i] = arr[(i + moveNumber) % arr.length];
}
for(int i = 0; i < arr.length; i++) arr[i] = newArr[i];
System.out.println("所有元素向左移动" + moveNumber + "位后:");
System.out.print("[");
for (int i = 0; i < arr.length; i++) System.out.print(arr[i] + (i == arr.length - 1 ? "]\n" : ", "));
}
}
场景9:用数组简化多分支逻辑(生肖判断示例)
原switch多分支代码:
switch (year % 12) {
case 0 -> System.out.println("monkey");
case 1 -> System.out.println("rooster");
case 2 -> System.out.println("dog");
case 3 -> System.out.println("pig");
case 4 -> System.out.println("mouse");
case 5 -> System.out.println("ox");
case 6 -> System.out.println("tiger");
case 7 -> System.out.println("rabbit");
case 8 -> System.out.println("dragon");
case 9 -> System.out.println("snake");
case 10 -> System.out.println("horse");
case 11 -> System.out.println("sheep");
default -> System.out.println();
}
用数组简化后(更简洁、易维护):
String[] years = {"monkey","rooster","dog","pig","mouse","ox","tiger","rabbit","dragon","snake","horse","sheep"};
System.out.println(years[year % 12]); // 直接通过索引获取结果
数组实战示例
示例1:统计大于平均值的数字个数
需求:让用户输入数字个数,再输入对应数字,计算平均值并统计大于平均值的数字数量。
package com.method_array;
import java.util.Scanner;
/**
* @Author Jing61
*/
public class AnalyzeNumber {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入一个正整数表示读取的数量:");
int number = input.nextInt();
// 初始化数组并接收用户输入
double[] arr = new double[number];
for (int i = 0; i < arr.length; i++) {
System.out.println("请输入第" + (i + 1) + "个数字:");
arr[i] = input.nextDouble();
}
// 调用方法计算结果并输出
System.out.println("平均数:" + getAverage(arr));
System.out.println("大于平均数的个数:" + getAboveAverageCount(arr, getAverage(arr)));
input.close();
}
// 计算数组平均值
private static double getAverage(double[] arr) {
double sum = 0;
for (double i : arr) {
sum += i;
}
return sum / arr.length;
}
// 统计大于平均值的数字个数
private static int getAboveAverageCount(double[] arr, double average) {
int count = 0;
for (double i : arr) {
if(i > average) {
count++;
}
}
return count;
}
}
示例2:模拟从52张扑克牌中随机抽4张
需求:用数组表示52张牌,打乱后随机抽取4张并显示花色和点数。
package com.method_array;
/**
* @Author Jing61
*/
public class DeckDemo {
public static void main(String[] args) {
// 1. 初始化52张牌(0~51代表52张牌)
int[] deck = new int[52];
for(int i = 0; i < deck.length; i++) {
deck[i] = i;
}
// 2. 洗牌(打乱数组)
for(int i = 0; i < deck.length; i++) {
int randomIndex = (int)(Math.random() * deck.length); // 随机索引
// 交换当前元素与随机索引元素
int temp = deck[i];
deck[i] = deck[randomIndex];
deck[randomIndex] = temp;
}
// 3. 定义花色和点数数组(与牌的索引对应)
String[] suits = {"♠", "♥", "♣", "♦"}; // 花色:黑桃、红桃、梅花、方块
String[] ranks = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"}; // 点数
// 4. 抽取前4张牌并显示
for(int i = 0; i < 4; i++) {
int cardNumber = deck[i];
String suit = suits[cardNumber / 13]; // 花色:0~12→0(黑桃),13~25→1(红桃),以此类推
String rank = ranks[cardNumber % 13]; // 点数:0~12对应A~K
System.out.println("第" + (i+1) + "张牌:" + suit + rank);
}
}
}
数组遍历:foreach循环
foreach循环(增强for循环)是Java提供的简化数组遍历的语法,无需手动控制索引,直接迭代数组中每个元素。
语法格式
for (元素类型 变量名 : 数组名) {
// 处理变量(变量代表当前迭代的数组元素)
}
示例:遍历数组并打印元素
package com.method_array;
/**
* @Author Jing61
*/
public class ArrayDemo {
public static void main(String[] args) {
double[] arr = new double[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = Math.random() * 100;
}
// foreach循环遍历数组
System.out.println("数组元素:");
for (double element : arr) {
System.out.println(element); // element依次代表arr[0], arr[1], ..., arr[9]
}
}
}
注意事项
foreach循环只能遍历元素,无法修改数组元素的值(若需修改,需用普通for循环通过索引操作)。- 若需按非顺序(如倒序)遍历数组,或需要索引值,仍需使用普通
for循环。
数组复制
要将一个数组中的内容复制到另外一个数组中,需要将数组的每一个元素复制到另外一个数组中。在程序中经常需要复制一个数组或数组的一部分。在这种情况下,可能会尝试使用赋值语句(=),如:list2 = list1;,
该语句并不能将 list1 引用的数组内容复制给 list2,而只是将 list1 的引用值赋值给了 list2。在这条语句后,list1 和 list2 都指向同一个数组,如下图所示。list2 原先引用的数组不能再引用,它就变成了垃圾,会被java虚拟机自动收回(垃圾回收)。

这样就意味着,修改 list2,list1 同样也会被修改,修改 list1,list2 也会该被修改,例如:
package com.method_array;
/**
* @Author Jing61
*/
public class ArrayDemo {
public static void main(String[] args) {
int[] list1 = {1, 2, 3, 4, 5};
int[] list2 = new int[5];
list2 = list1;
for (int i = 0; i < 5; i++) {
System.out.print(list2[i] + " "); // 1 2 3 4 5
}
list2[3] = 77;
System.out.println("\nlist2: ");
for (int i = 0; i < 5; i++) {
System.out.print(list2[i] + " "); // 1 2 3 77 5
}
System.out.println("\nlist1: ");
for (int i = 0; i < 5; i++) {
System.out.print(list1[i] + " "); // 1 2 3 77 5
}
}
}
在Java中,可以使用赋值语句复制基本数据类型的变量,但不能复制数组。将一个数组变量赋值给另一个数组变量,实际上是将一个数组的引用赋值给另一个变量,使两个变量都指向相同的内存地址。
复制数组的三种方法
方式1:使用普通for循环逐个复制
通过遍历原数组,将每个元素赋值到新数组对应位置。
// 原数组
int[] sourceArray = {2, 5, 8, 10, 200, -20};
// 新数组(长度与原数组一致)
int[] targetArray = new int[sourceArray.length];
// 逐个复制元素
for (int i = 0; i < sourceArray.length; i++) {
targetArray[i] = sourceArray[i];
}
方式2:使用System.arraycopy()方法
System类提供的静态方法,专门用于数组复制,效率高于手动循环。
方法参数说明
System.arraycopy(
源数组, // src: 要复制的原数组
源数组起始索引, // srcPos: 从原数组的哪个索引开始复制
目标数组, // dest: 复制到的目标数组
目标数组起始索引,// destPos: 复制到目标数组的哪个索引
复制元素个数 // length: 要复制的元素数量
);
示例
int[] sourceArray = {2, 5, 8, 10, 200, -20};
int[] targetArray = new int[sourceArray.length];
// 复制原数组所有元素到目标数组
System.arraycopy(sourceArray, 0, targetArray, 0, sourceArray.length);
方式3:使用数组的clone()方法
数组对象的clone()方法会创建一个新数组,并复制原数组的所有元素,返回新数组的引用。
int[] sourceArray = {2, 5, 8, 10, 200, -20};
// 调用clone()复制,无需手动创建新数组
int[] targetArray = sourceArray.clone();
数组与方法的交互
数组作为引用数据类型,与方法的交互有两种场景:数组作为方法参数、数组作为方法返回值。
数组作为方法参数
数组传递给方法时,本质是传递数组的引用(而非副本)。方法内部修改数组元素,会影响方法外部的原数组。
示例:方法中修改数组的值
// 方法接收数组参数,返回最大值
public static double change(double[] arr) {
arr[0] = 55;
return arr[0];
}
// 调用方法
public static void main(String[] args) {
double[] scores = {88, 95, 76, 92, 85};
System.out.println("函数值:" + change(scores) + "scores[0]:" + scores[0]);
// 输出:函数值:55.0scores[0]:55.0
}
数组作为方法返回值
方法可以返回一个数组(本质是返回数组的引用),常用于返回处理后的数组(如反转后的数组)。
示例:方法返回反转后的数组
/**
* 反转数组并返回新数组
* @param list 原数组
* @return 反转后的新数组
*/
public static int[] reverse(int[] list) {
int[] result = new int[list.length]; // 创建新数组存储结果
// 原数组从后往前,赋值到新数组从前往后
for (int i = 0, j = result.length - 1; i < list.length; i++, j--) {
result[j] = list[i];
}
return result; // 返回新数组引用
}
// 调用方法
public static void main(String[] args) {
int[] original = {1, 2, 3, 4, 5};
int[] reversed = reverse(original); // 接收反转后的数组
System.out.println(Arrays.toString(reversed)); // 输出[5, 4, 3, 2, 1]
}
实战:统计随机字母出现次数
需求:生成100个随机小写字母,统计每个字母(a~z)出现的次数。
package com.method_array;
/**
* @Author Jing61
*/
public class StatisticsLetterCount {
public static void main(String[] args) {
// 1. 创建100个随机小写字母数组
char[] letters = createLetters();
// 2. 统计并显示每个字母出现次数
showLetterCount(letters);
}
/**
* 生成单个随机小写字母(a~z)
* @return 随机小写字母
*/
public static char generateRandomLowerLetter() {
// 'a'的ASCII码是97,'z'是122,Math.random()*26生成0~25的随机数
return (char) ('a' + Math.random() * ('z' - 'a' + 1));
}
/**
* 创建包含100个随机小写字母的数组
* @return 随机字母数组
*/
public static char[] createLetters() {
char[] letters = new char[100];
for (int i = 0; i < letters.length; i++) {
letters[i] = generateRandomLowerLetter();
}
return letters;
}
/**
* 统计并显示每个字母出现次数
* @param letters 随机字母数组
*/
public static void showLetterCount(char[] letters) {
// times[0]对应'a'的次数,times[1]对应'b',...,times[25]对应'z'
int[] times = new int[26];
// 统计逻辑:字母-'a'得到对应索引,次数+1
for (int i = 0; i < letters.length; i++) {
times[letters[i] - 'a']++;
}
// 显示结果:每10个字母换行一次
for (int i = 0; i < times.length; i++) {
System.out.print((char) ('a' + i) + ":" + times[i] +
((i + 1) % 10 == 0 ? "\n" : "\t"));
}
}
}
可变长参数列表
Java允许方法接收数量不固定的同类型参数,称为“可变长参数”,其本质是一个数组。
语法格式
public 返回值类型 方法名(参数类型... 可变参数名) {
// 方法体(可变参数名可当作数组使用)
}
核心规则
- 一个方法只能有一个可变长参数。
- 可变长参数必须放在参数列表的最后一位(避免与其他参数歧义)。
示例:求任意个整数的和
package com.method_array;
/**
* @Author Jing61
*/
public class ArrayDemo {
public static void main(String[] args) {
// 调用方式1:直接传递多个整数
System.out.println(sum(1, 2, 3, 4, 5)); // 输出15
// 调用方式2:传递数组(可变参数本质是数组)
int[] arr = {1, 2, 3, 4, 5};
System.out.println(sum(arr)); // 输出15
}
// 可变长参数方法:求任意个int的和
public static int sum(int... nums) {
int total = 0;
// 可变参数nums当作数组遍历
for (int i : nums) {
total += i;
}
return total;
}
}
数组的查找算法
在数组中查找指定元素(关键字key),常用两种算法:线性查找(适用于无序数组)和二分查找(适用于有序数组)。
线性查找(顺序查找)
原理
从数组第一个元素开始,依次与key比较,找到则返回索引,遍历结束未找到则返回-1。
特点:适用于任意数组(有序/无序),时间复杂度O(n)(n为数组长度)。
代码实现
package com.method_array;
/**
* @Author Jing61
*/
public class LinearSearch {
public static void main(String[] args) {
int[] list = {2, 5, 7, 10, 14, 17, 19, 24, 28, 30};
System.out.println(linearSearch(list, 17));
}
/**
* 从数组的第一个元素依次的比较,如果该元素==关键字元素,返回该元素对应的索引。
* @param key 关键字
* @param list 数组
* @return 如果查找到该元素,就返回该元素对应的索引,没有找到返回-1
*/
public static int linearSearch(int[] list, int key) {
for(int i = 0; i < list.length; i++) {
if(key == list[i]) return i;
}
return -1;
}
}
二分查找(折半查找)
原理
前提:数组必须有序(升序)。
通过不断将数组中间元素与key比较,缩小查找范围:
- 定义
low(起始索引,初始0)、high(结束索引,初始length-1)。 - 计算中间索引
mid = (low + high) / 2,比较list[mid]与key:- 若
key < list[mid]:key在左半部分,更新high = mid - 1。 - 若
key == list[mid]:找到,返回mid。 - 若
key > list[mid]:key在右半部分,更新low = mid + 1。
- 若
- 循环直至
low > high,未找到返回-1。
特点:效率高,时间复杂度O(log n),但依赖数组有序。
代码实现
package com.method_array;
/**
* @Author Jing61
*/
public class BinarySearch {
public static void main(String[] args) {
int[] list = {2, 4, 7, 10, 11, 45, 50, 59, 60, 66, 69, 70, 79};
System.out.println(binarySearch(list, 11));
}
public static int binarySearch(int[] list, int key) {
int low = 0;
int high = list.length - 1;
while(high >= low) {
int mid = (low + high) / 2;
if(key < list[mid]) high = mid - 1;
else if(key == list[mid]) return mid;
else low = mid + 1;
}
return -1;
}
}
二维数组
二维数组本质是“数组的数组”,可理解为一个表格(行×列结构),适用于存储具有行列关系的数据(如矩阵、学生成绩表)。
二维数组的定义与初始化
二维数组的元素类型可以是基本数据类型或引用类型,声明时需指定元素类型和数组名。
声明语法
// 推荐写法
元素类型[][] 数组名;
// 不推荐(可读性差)
元素类型 数组名[][];
元素类型[] 数组名[];
初始化方式
二维数组的初始化分为静态初始化和动态初始化,且支持“不规则数组”(每行长度不同)。
静态初始化
直接指定每行的元素值,行数由初始化时的大括号组数决定,每行长度可不同。
// 规则数组(每行长度相同)
int[][] matrix1 = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 不规则数组(每行长度不同)
int[][] matrix2 = {
{1, 2},
{3},
{4, 5, 6}
};
动态初始化
分两步:先指定行数,再为每行分配长度(可统一或单独指定)。
// 方式1:统一指定行列数(规则数组)
int[][] scores = new int[3][4]; // 3行4列,所有元素默认值为0
// 方式2:先指定行数,再单独指定每行长度(支持不规则数组)
int[][] nums = new int[2][]; // 2行,暂不指定列数
nums[0] = new int[3]; // 第1行3列
nums[1] = new int[5]; // 第2行5列(与第1行长度不同)
二维数组的元素访问
通过“数组名[行索引][列索引] ”访问元素,行索引和列索引均从0开始,最大值分别为“行数-1”和“对应行的列数-1”。
示例
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 访问第2行第3列的元素(值为6)
int value = matrix[1][2];
// 修改第1行第1列的元素为10
matrix[0][0] = 10;
注意事项
- 访问不存在的行或列会抛出
ArrayIndexOutOfBoundsException。 - 需先初始化行,再访问该行的元素(否则会抛出
NullPointerException)。
二维数组的长度与遍历
长度获取
数组名.length:获取二维数组的行数。数组名[行索引].length:获取指定行的列数(每行长度可能不同)。
遍历方式
二维数组的遍历需嵌套循环(外层循环遍历行,内层循环遍历列)。
普通for循环遍历
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 外层循环遍历行
for (int i = 0; i < matrix.length; i++) {
// 内层循环遍历第i行的列
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println(); // 每行结束后换行
}
foreach循环遍历
for (int[] row : matrix) { // 外层遍历每行(row是一维数组)
for (int num : row) { // 内层遍历当前行的元素
System.out.print(num + " ");
}
System.out.println();
}
二维数组实战示例
示例1:计算二维数组所有元素的和
package com.method_array;
/**
* @Author Jing61
*/
public class TwoDArraySum {
public static void main(String[] args) {
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int total = 0;
// 累加所有元素
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
total += matrix[i][j];
}
}
System.out.println("二维数组所有元素的和:" + total); // 输出45
}
}
示例2:生成随机3×3矩阵并计算每行的和
package com.method_array;
/**
* @Author Jing61
*/
public class MatrixRowSum {
public static void main(String[] args) {
// 生成3×3的随机整数矩阵(1~100)
int[][] matrix = new int[3][3];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
matrix[i][j] = (int) (Math.random() * 100) + 1;
}
}
// 打印矩阵
System.out.println("随机矩阵:");
for (int[] row : matrix) {
for (int num : row) {
System.out.print(num + "\t");
}
System.out.println();
}
// 计算每行的和
System.out.println("\n每行的和:");
for (int i = 0; i < matrix.length; i++) {
int rowSum = 0;
for (int j = 0; j < matrix[i].length; j++) {
rowSum += matrix[i][j];
}
System.out.println("第" + (i + 1) + "行:" + rowSum);
}
}
}
示例3:矩阵转置(行变列,列变行)
package com.method_array;
/**
* @Author Jing61
*/
public class MatrixTranspose {
public static void main(String[] args) {
// 原矩阵(3行2列)
int[][] original = {
{1, 2},
{3, 4},
{5, 6}
};
// 转置后的矩阵(2行3列)
int[][] transposed = new int[original[0].length][original.length];
// 执行转置:transposed[j][i] = original[i][j]
for (int i = 0; i < original.length; i++) {
for (int j = 0; j < original[i].length; j++) {
transposed[j][i] = original[i][j];
}
}
// 打印原矩阵
System.out.println("原矩阵:");
for (int[] row : original) {
for (int num : row) {
System.out.print(num + " ");
}
System.out.println();
}
// 打印转置后的矩阵
System.out.println("转置后的矩阵:");
for (int[] row : transposed) {
for (int num : row) {
System.out.print(num + " ");
}
System.out.println();
}
}
}
二维数组与方法的交互
二维数组作为方法参数或返回值时,传递的是数组的引用,方法内部对元素的修改会影响外部数组。
示例:方法返回一个二维数组(矩阵)
package com.method_array;
/**
* @Author Jing61
*/
public class MatrixGenerator {
public static void main(String[] args) {
// 调用方法生成3×3的随机矩阵
int[][] matrix = generateRandomMatrix(3, 3, 1, 100);
// 打印矩阵
for (int[] row : matrix) {
for (int num : row) {
System.out.print(num + "\t");
}
System.out.println();
}
}
/**
* 生成指定行列数的随机整数矩阵
* @param rows 行数
* @param cols 列数
* @param min 随机数最小值(包含)
* @param max 随机数最大值(包含)
* @return 生成的二维数组
*/
public static int[][] generateRandomMatrix(int rows, int cols, int min, int max) {
int[][] matrix = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
// 生成[min, max]范围的随机整数
matrix[i][j] = (int) (Math.random() * (max - min + 1)) + min;
}
}
return matrix;
}
}
不规则二维数组的应用
不规则数组(每行长度不同)适用于存储“每行元素数量不一致”的数据,例如不同班级的学生人数不同时的成绩表。
示例:存储3个班级的成绩(班级人数分别为3、2、4)
package com.method_array;
/**
* @Author Jing61
*/
public class IrregularArray {
public static void main(String[] args) {
// 初始化不规则数组(3个班级,人数不同)
int[][] scores = {
{90, 85, 92}, // 班级1:3人
{88, 76}, // 班级2:2人
{95, 89, 78, 91}// 班级3:4人
};
// 打印每个班级的成绩和平均分
for (int i = 0; i < scores.length; i++) {
int sum = 0;
System.out.print("班级" + (i + 1) + "成绩:");
for (int j = 0; j < scores[i].length; j++) {
sum += scores[i][j];
System.out.print(scores[i][j] + " ");
}
double avg = (double) sum / scores[i].length;
System.out.println(",平均分:" + avg);
}
}
}

浙公网安备 33010602011771号