引言
在 Java 编程中,数组是一种基础且重要的数据结构,它允许我们将多个相同类型的元素存储在一个连续的内存空间中,通过索引快速访问。掌握数组的使用是学习 Java 集合框架、算法等高级知识的基础。本章将从数组的创建、使用开始,逐步深入到 Arrays 工具类、二维数组的应用,最后通过实战案例巩固所学知识。
思维导图
5.1 创建和使用数组
5.1.1 数组定义
数组是相同数据类型元素的有序集合,它具有固定长度,一旦创建不可改变。在 Java 中,数组属于引用类型,需要经历声明→创建→初始化三个步骤。
数组的声明方式
// 方式1:数据类型[] 数组名;(推荐,更清晰表示数组类型)
int[] numbers;
String[] names;// 方式2:数据类型 数组名[];(兼容C语言风格)
int scores[];
数组的创建(动态初始化)
使用new
关键字创建数组,指定长度,元素会被赋予默认值(数值型为 0,布尔型为 false,引用类型为 null):
// 声明并创建数组
int[] ages = new int[5]; // 创建长度为5的int数组
String[] fruits = new String[3]; // 创建长度为3的String数组
数组的初始化(静态初始化)
直接指定数组元素的值,长度由元素个数决定:
// 静态初始化完整格式
int[] nums = new int[]{1, 2, 3, 4, 5};// 简化格式(最常用)
String[] colors = {"red", "green", "blue"};
数组的访问
通过索引(从 0 开始)访问数组元素,使用数组名[索引]
:
public class ArrayDefinitionDemo {public static void main(String[] args) {// 静态初始化数组String[] languages = {"Java", "Python", "C++"};// 访问数组元素System.out.println("数组长度:" + languages.length); // 输出:3System.out.println("第一个元素:" + languages[0]); // 输出:Java// 修改数组元素languages[1] = "JavaScript";System.out.println("修改后第二个元素:" + languages[1]); // 输出:JavaScript// 遍历数组(普通for循环)for (int i = 0; i < languages.length; i++) {System.out.println("索引" + i + ":" + languages[i]);}}
}
注意:访问数组时如果索引超出范围(
>=length
或<0
),会抛出ArrayIndexOutOfBoundsException
异常。
5.1.2 增强的 for 循环
增强 for 循环(foreach 循环)是 Java 5 引入的语法,专门用于遍历数组或集合,简化遍历代码。
语法格式
for (元素类型 变量名 : 数组名) {// 循环体,变量名表示当前元素
}
普通 for 循环 vs 增强 for 循环
public class ForEachDemo {public static void main(String[] args) {int[] scores = {85, 92, 78, 90, 88};// 普通for循环:可修改元素,需控制索引System.out.println("普通for循环遍历:");for (int i = 0; i < scores.length; i++) {scores[i] += 2; // 加分操作System.out.print(scores[i] + " ");}// 增强for循环:不可修改元素(变量是副本),无需控制索引System.out.println("\n增强for循环遍历:");for (int score : scores) {System.out.print(score + " ");}}
}
运行结果
注意:增强 for 循环中不能修改数组元素的值(变量是元素的副本),适合单纯的遍历场景;需要修改元素或使用索引时,仍需用普通 for 循环。
5.1.3 数组元素的复制
数组复制是常见操作,Java 提供多种方式实现数组复制:手动复制、System.arraycopy()
、Arrays.copyOf()
(后续 5.2.3 讲解)。
手动复制(循环赋值)
int[] source = {1, 2, 3, 4, 5};
int[] target = new int[source.length];
for (int i = 0; i < source.length; i++) {target[i] = source[i];
}
System.arraycopy () 方法
JDK 提供的 native 方法,效率高,语法:
System.arraycopy(源数组, 源起始索引, 目标数组, 目标起始索引, 复制长度);
示例代码
public class ArrayCopyDemo {public static void main(String[] args) {int[] source = {10, 20, 30, 40, 50};int[] target = new int[6]; // 目标数组长度6// 复制source的索引1开始的3个元素到target的索引2开始System.arraycopy(source, 1, target, 2, 3);// 遍历目标数组for (int num : target) {System.out.print(num + " "); // 输出:0 0 20 30 40 0 }}
}
注意:
System.arraycopy()
要求目标数组有足够空间,否则会抛出IndexOutOfBoundsException
。
5.1.4 数组参数与返回值
数组作为引用类型,可以作为方法的参数或返回值,传递的是数组的引用(内存地址)。
数组作为参数(引用传递)
// 方法:打印数组元素
public static void printArray(int[] arr) {for (int num : arr) {System.out.print(num + " ");}System.out.println();
}// 方法:修改数组元素(会影响原数组)
public static void modifyArray(int[] arr) {for (int i = 0; i < arr.length; i++) {arr[i] *= 2;}
}
数组作为返回值
// 方法:创建并返回一个int数组
public static int[] createArray(int length) {int[] arr = new int[length];for (int i = 0; i < length; i++) {arr[i] = i + 1;}return arr;
}
完整示例
public class ArrayParamReturnDemo {public static void main(String[] args) {int[] nums = {1, 2, 3, 4};System.out.println("原数组:");printArray(nums); // 输出:1 2 3 4 modifyArray(nums);System.out.println("修改后数组:");printArray(nums); // 输出:2 4 6 8 int[] newArr = createArray(5);System.out.println("方法返回的数组:");printArray(newArr); // 输出:1 2 3 4 5 }// 打印数组public static void printArray(int[] arr) {if (arr == null) {System.out.println("数组为空");return;}for (int num : arr) {System.out.print(num + " ");}System.out.println();}// 修改数组元素public static void modifyArray(int[] arr) {if (arr == null) return;for (int i = 0; i < arr.length; i++) {arr[i] *= 2;}}// 创建数组public static int[] createArray(int length) {if (length <= 0) {return null; // 处理无效长度}int[] arr = new int[length];for (int i = 0; i < length; i++) {arr[i] = i + 1;}return arr;}
}
5.1.5 可变参数的方法
Java 5 引入可变参数(varargs),允许方法接收任意数量的相同类型参数,语法为类型... 参数名
。
语法格式
public static 返回类型 方法名(类型... 参数名) {// 方法体中参数名可作为数组使用
}
使用规则
- 一个方法只能有一个可变参数
- 可变参数必须是方法的最后一个参数
- 调用时可传递 0 个、1 个或多个参数,也可直接传递数组
示例代码
public class VarargsDemo {public static void main(String[] args) {// 调用可变参数方法sum(); // 0个参数sum(1); // 1个参数sum(1, 2, 3); // 多个参数sum(new int[]{4, 5, 6}); // 传递数组}// 可变参数方法:计算多个整数的和public static void sum(int... nums) {int total = 0;for (int num : nums) {total += num;}System.out.println("总和:" + total);}// 混合参数(可变参数在最后)public static void printInfo(String name, int... scores) {System.out.println("姓名:" + name);System.out.println("成绩:");for (int score : scores) {System.out.print(score + " ");}System.out.println("\n---");}
}
运行结果
5.1.6 实例:随机抽取 4 张牌
需求分析
模拟从 52 张扑克牌中随机抽取 4 张,不重复。扑克牌由 “花色” 和 “点数” 组成,需避免重复抽取。
实现思路
- 定义花色数组(红桃、黑桃、方块、梅花)和点数数组(A,2-10,J,Q,K)
- 使用两个数组记录已抽取的索引,避免重复
- 随机生成花色和点数的索引,检查是否已抽取,未抽取则记录并输出
完整代码
import java.util.Random;/*** 随机抽取4张扑克牌示例*/
public class CardDrawing {public static void main(String[] args) {// 定义花色和点数数组String[] suits = {"红桃", "黑桃", "方块", "梅花"};String[] ranks = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};// 记录已抽取的牌的索引(避免重复)boolean[] drawn = new boolean[52]; // 52张牌,初始值为falseint count = 0; // 已抽取的牌数Random random = new Random();System.out.println("随机抽取的4张牌:");// 循环抽取4张牌while (count < 4) {// 生成随机索引(0-51)int index = random.nextInt(52);// 如果未抽取过if (!drawn[index]) {drawn[index] = true; // 标记为已抽取count++; // 计数+1// 计算花色和点数索引int suitIndex = index / 13; // 0-3(每13张一种花色)int rankIndex = index % 13; // 0-12// 输出牌面System.out.println(suits[suitIndex] + ranks[rankIndex]);}}}
}
运行结果(示例)
5.1.7 实例:一个整数栈类
需求分析
实现一个整数栈(Stack),支持入栈(push)、出栈(pop)、查看栈顶元素(peek)、判断栈空(isEmpty)、判断栈满(isFull)等操作。
实现思路
- 用数组作为栈的底层存储结构
- 定义栈顶指针(top),初始值为 - 1(栈空)
- 入栈:top+1,存入元素;出栈:返回 top 位置元素,top-1
类图(PlantUML)
class IntStack {- int[] elements // 存储栈元素的数组- int top // 栈顶指针(-1表示栈空)- int capacity // 栈的容量+ IntStack(int capacity) // 构造方法:初始化栈容量+ push(int value): boolean // 入栈+ pop(): Integer // 出栈(返回null表示栈空)+ peek(): Integer // 查看栈顶元素+ isEmpty(): boolean // 判断栈空+ isFull(): boolean // 判断栈满+ size(): int // 获取当前栈元素个数
}
流程图(入栈操作)
完整代码
/*** 整数栈类实现*/
public class IntStack {private int[] elements; // 存储栈元素的数组private int top; // 栈顶指针(-1表示栈空)private int capacity; // 栈的最大容量/*** 构造方法:初始化栈容量* @param capacity 栈的最大容量*/public IntStack(int capacity) {this.capacity = capacity;elements = new int[capacity];top = -1; // 初始栈空}/*** 入栈操作* @param value 要入栈的整数* @return 入栈成功返回true,栈满则返回false*/public boolean push(int value) {if (isFull()) {System.out.println("栈已满,无法入栈!");return false;}top++; // 栈顶指针上移elements[top] = value; // 存入元素return true;}/*** 出栈操作* @return 出栈的元素,栈空则返回null*/public Integer pop() {if (isEmpty()) {System.out.println("栈为空,无法出栈!");return null;}int value = elements[top]; // 获取栈顶元素top--; // 栈顶指针下移return value;}/*** 查看栈顶元素(不出栈)* @return 栈顶元素,栈空则返回null*/public Integer peek() {if (isEmpty()) {return null;}return elements[top];}/*** 判断栈是否为空* @return 空返回true,否则返回false*/public boolean isEmpty() {return top == -1;}/*** 判断栈是否已满* @return 满返回true,否则返回false*/public boolean isFull() {return top == capacity - 1;}/*** 获取当前栈中元素个数* @return 元素个数*/public int size() {return top + 1;}/*** 测试栈功能*/public static void main(String[] args) {IntStack stack = new IntStack(3); // 创建容量为3的栈// 测试入栈stack.push(10);stack.push(20);stack.push(30);stack.push(40); // 栈满,入栈失败// 测试栈状态System.out.println("栈是否满:" + stack.isFull()); // trueSystem.out.println("栈元素个数:" + stack.size()); // 3System.out.println("栈顶元素:" + stack.peek()); // 30// 测试出栈System.out.println("出栈元素:" + stack.pop()); // 30System.out.println("出栈元素:" + stack.pop()); // 20System.out.println("栈元素个数:" + stack.size()); // 1// 继续出栈System.out.println("出栈元素:" + stack.pop()); // 10System.out.println("出栈元素:" + stack.pop()); // 栈空,返回nullSystem.out.println("栈是否空:" + stack.isEmpty()); // true}
}
运行结果
5.2 Arrays 类
java.util.Arrays
类提供了大量静态方法,用于数组的操作(排序、查找、复制等),简化数组处理代码。使用前需导入该类。
5.2.1 数组的排序
Arrays.sort()
方法用于对数组进行排序,支持基本数据类型和对象数组(对象需实现Comparable
接口)。
示例代码
import java.util.Arrays;/*** Arrays.sort()排序示例*/
public class ArraysSortDemo {public static void main(String[] args) {// 基本类型数组排序(升序)int[] intArr = {3, 1, 4, 1, 5, 9};Arrays.sort(intArr);System.out.println("排序后的int数组:" + Arrays.toString(intArr));// 字符串数组排序(按字典序)String[] strArr = {"banana", "apple", "orange", "grape"};Arrays.sort(strArr);System.out.println("排序后的字符串数组:" + Arrays.toString(strArr));// 部分排序(从索引1到4,不包含4)int[] partArr = {5, 3, 8, 2, 7, 1};Arrays.sort(partArr, 1, 4); // 排序索引1-3的元素System.out.println("部分排序后的数组:" + Arrays.toString(partArr));}
}
运行结果
5.2.2 元素的查找
Arrays.binarySearch()
方法用于在已排序的数组中查找元素,返回元素索引(未找到返回负数)。
语法格式
// 在整个数组中查找
static int binarySearch(数组, 目标值)// 在指定范围(fromIndex到toIndex)中查找
static int binarySearch(数组, fromIndex, toIndex, 目标值)
示例代码
import java.util.Arrays;/*** Arrays.binarySearch()查找示例*/
public class ArraysSearchDemo {public static void main(String[] args) {int[] arr = {2, 4, 6, 8, 10, 12};// 查找存在的元素int index1 = Arrays.binarySearch(arr, 8);System.out.println("元素8的索引:" + index1); // 输出:3// 查找不存在的元素int index2 = Arrays.binarySearch(arr, 5);System.out.println("元素5的索引(未找到):" + index2); // 输出:-3(插入点为2,-(2+1)=-3)// 范围查找int index3 = Arrays.binarySearch(arr, 1, 4, 6); // 在索引1-3中查找6System.out.println("范围查找元素6的索引:" + index3); // 输出:2}
}
注意:使用
binarySearch()
前必须确保数组已排序,否则结果不可靠!
5.2.3 数组元素的复制
Arrays
类提供copyOf()
和copyOfRange()
方法复制数组,相比System.arraycopy()
更简洁。
方法说明
copyOf(原数组, 新长度)
:复制原数组到新数组,新长度可大于或小于原长度(不足补默认值,超出截断)copyOfRange(原数组, 起始索引, 结束索引)
:复制原数组从起始索引到结束索引(不包含)的元素
示例代码
import java.util.Arrays;/*** Arrays.copyOf()和copyOfRange()示例*/
public class ArraysCopyDemo {public static void main(String[] args) {int[] original = {1, 2, 3, 4, 5};// copyOf():新长度等于原长度int[] copy1 = Arrays.copyOf(original, 5);System.out.println("copy1:" + Arrays.toString(copy1)); // [1,2,3,4,5]// copyOf():新长度大于原长度(补默认值0)int[] copy2 = Arrays.copyOf(original, 7);System.out.println("copy2:" + Arrays.toString(copy2)); // [1,2,3,4,5,0,0]// copyOf():新长度小于原长度(截断)int[] copy3 = Arrays.copyOf(original, 3);System.out.println("copy3:" + Arrays.toString(copy3)); // [1,2,3]// copyOfRange():复制索引1到4(不包含4)的元素int[] rangeCopy = Arrays.copyOfRange(original, 1, 4);System.out.println("rangeCopy:" + Arrays.toString(rangeCopy)); // [2,3,4]}
}
5.2.4 填充数组元素
Arrays.fill()
方法用于为数组的指定范围填充相同的值。
示例代码
import java.util.Arrays;/*** Arrays.fill()填充数组示例*/
public class ArraysFillDemo {public static void main(String[] args) {// 初始化数组int[] arr1 = new int[5];// 填充整个数组为8Arrays.fill(arr1, 8);System.out.println("填充整个数组:" + Arrays.toString(arr1)); // [8,8,8,8,8]// 部分填充:索引1到4(不包含4)填充为5int[] arr2 = {1, 2, 3, 4, 5, 6};Arrays.fill(arr2, 1, 4, 5);System.out.println("部分填充后:" + Arrays.toString(arr2)); // [1,5,5,5,5,6]// 二维数组填充(填充每行的数组)String[][] strArr = new String[3][3];for (int i = 0; i < strArr.length; i++) {Arrays.fill(strArr[i], "A" + i); // 第i行填充"Ai"}System.out.println("二维数组填充后:");for (String[] row : strArr) {System.out.println(Arrays.toString(row));}}
}
5.2.5 数组的比较
Arrays.equals()
用于比较两个数组是否相等(长度相同且对应元素相等);Arrays.deepEquals()
用于比较多维数组。
示例代码
import java.util.Arrays;/*** 数组比较示例*/
public class ArraysEqualsDemo {public static void main(String[] args) {// 一维数组比较int[] arr1 = {1, 2, 3};int[] arr2 = {1, 2, 3};int[] arr3 = {1, 2, 4};System.out.println("arr1与arr2是否相等:" + Arrays.equals(arr1, arr2)); // trueSystem.out.println("arr1与arr3是否相等:" + Arrays.equals(arr1, arr3)); // false// 长度不同的数组int[] arr4 = {1, 2};System.out.println("arr1与arr4是否相等:" + Arrays.equals(arr1, arr4)); // false// 二维数组比较(需用deepEquals)int[][] deepArr1 = {{1, 2}, {3, 4}};int[][] deepArr2 = {{1, 2}, {3, 4}};System.out.println("二维数组用equals比较:" + Arrays.equals(deepArr1, deepArr2)); // false(比较的是引用)System.out.println("二维数组用deepEquals比较:" + Arrays.deepEquals(deepArr1, deepArr2)); // true}
}
5.3 二维数组
二维数组本质是 “数组的数组”,即每个元素都是一个一维数组。常用于表示表格、矩阵等二维结构。
5.3.1 二维数组定义
定义方式
// 方式1:声明并指定行数和列数
数据类型[][] 数组名 = new 数据类型[行数][列数];// 方式2:声明时不指定列数(不规则数组)
数据类型[][] 数组名 = new 数据类型[行数][];// 方式3:静态初始化
数据类型[][] 数组名 = {{元素1,元素2}, {元素3,元素4}, ...};
示例代码
/*** 二维数组定义示例*/
public class TwoDArrayDefine {public static void main(String[] args) {// 方式1:指定行数和列数(3行2列)int[][] arr1 = new int[3][2];System.out.println("arr1行数:" + arr1.length); // 3System.out.println("arr1第0行列数:" + arr1[0].length); // 2// 方式2:只指定行数,不指定列数(后续需初始化每行)int[][] arr2 = new int[2][];arr2[0] = new int[3]; // 第0行3列arr2[1] = new int[4]; // 第1行4列System.out.println("arr2第1行列数:" + arr2[1].length); // 4// 方式3:静态初始化String[][] arr3 = {{"张三", "男"}, {"李四", "女"}, {"王五", "男"}};System.out.println("arr3第2行第0列:" + arr3[2][0]); // 王五}
}
5.3.2 数组元素的使用
二维数组元素通过数组名[行索引][列索引]
访问,行索引和列索引均从 0 开始。
示例代码
/*** 二维数组元素访问示例*/
public class TwoDArrayAccess {public static void main(String[] args) {// 创建3行3列的二维数组int[][] matrix = new int[3][3];// 给元素赋值(填充为1-9)int value = 1;for (int i = 0; i < matrix.length; i++) { // 遍历行for (int j = 0; j < matrix[i].length; j++) { // 遍历列matrix[i][j] = value++;}}// 访问并打印元素System.out.println("二维数组元素:");for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < matrix[i].length; j++) {System.out.print(matrix[i][j] + " ");}System.out.println(); // 换行}// 增强for循环遍历System.out.println("增强for循环遍历:");for (int[] row : matrix) { // 每行是一个int数组for (int num : row) {System.out.print(num + " ");}System.out.println();}}
}
运行结果
5.3.3 数组初始化器
二维数组的初始化包括静态初始化(直接指定元素)和动态初始化(先指定行数,再初始化每行)。
示例代码
import java.util.Arrays; // 添加Arrays导入/*** 二维数组初始化示例*/
public class TwoDArrayInit {public static void main(String[] args) {// 静态初始化:直接指定所有元素String[][] names = {{"Alice", "Bob"},{"Charlie", "David", "Eve"},{"Frank"}};// 打印静态初始化的数组System.out.println("静态初始化的二维数组:");for (String[] row : names) {System.out.println(Arrays.toString(row)); // 需要Arrays导入}// 动态初始化:先指定行数,再初始化每行int[][] dynamicArr = new int[2][];// 修复初始化语法错误dynamicArr[0] = new int[2]; // 先声明大小dynamicArr[0][0] = 10; // 再赋值dynamicArr[0][1] = 20;dynamicArr[1] = new int[3]; // 先声明大小dynamicArr[1][0] = 30; // 再赋值dynamicArr[1][1] = 40;dynamicArr[1][2] = 50;// 或者使用简化的正确语法:// dynamicArr[0] = new int[]{10, 20}; // 正确语法// dynamicArr[1] = new int[]{30, 40, 50}; // 正确语法System.out.println("\n动态初始化的二维数组:");for (int[] row : dynamicArr) {System.out.println(Arrays.toString(row)); // 需要Arrays导入}}
}
运行结果
5.3.4 实例:矩阵乘法
需求分析
实现两个矩阵的乘法:若 A 是 m×n 矩阵,B 是 n×p 矩阵,则乘积 C 是 m×p 矩阵,其中C[i][j] = A[i][0]*B[0][j] + A[i][1]*B[1][j] + ... + A[i][n-1]*B[n-1][j]
。
流程图(矩阵乘法)
完整代码
import java.util.Arrays;/*** 矩阵乘法示例*/
public class MatrixMultiplication {/*** 矩阵乘法* @param A 第一个矩阵(m×n)* @param B 第二个矩阵(n×p)* @return 乘积矩阵C(m×p),若不可乘返回null*/public static int[][] multiply(int[][] A, int[][] B) {// 检查矩阵合法性if (A == null || B == null) return null;int m = A.length; // A的行数int n = A[0].length; // A的列数int p = B[0].length; // B的列数// 检查A的列数是否等于B的行数if (n != B.length) {System.out.println("矩阵不可乘!A的列数(" + n + ")≠ B的行数(" + B.length + ")");return null;}// 创建结果矩阵(m行p列)int[][] C = new int[m][p];// 计算矩阵乘积for (int i = 0; i < m; i++) { // 遍历A的行for (int j = 0; j < p; j++) { // 遍历B的列int sum = 0;for (int k = 0; k < n; k++) { // 累加计算C[i][j]sum += A[i][k] * B[k][j];}C[i][j] = sum;}}return C;}/*** 打印矩阵* @param matrix 要打印的矩阵*/public static void printMatrix(int[][] matrix) {if (matrix == null) {System.out.println("矩阵为空");return;}for (int[] row : matrix) {System.out.println(Arrays.toString(row));}}public static void main(String[] args) {// 定义两个可乘的矩阵(2×3 和 3×2)int[][] A = {{1, 2, 3},{4, 5, 6}};int[][] B = {{7, 8},{9, 10},{11, 12}};System.out.println("矩阵A:");printMatrix(A);System.out.println("\n矩阵B:");printMatrix(B);// 计算乘积int[][] C = multiply(A, B);System.out.println("\n矩阵乘积C = A×B:");printMatrix(C);}
}
运行结果
5.3.5 不规则二维数组
不规则二维数组指每行的列数不同的二维数组,创建时只需指定行数,每行单独初始化。
示例代码
import java.util.Arrays;/*** 不规则二维数组示例*/
public class IrregularArray {public static void main(String[] args) {// 创建3行的不规则数组(不指定列数)int[][] irregular = new int[3][];// 初始化每行(列数不同)irregular[0] = new int[2]; // 第0行2列irregular[1] = new int[4]; // 第1行4列irregular[2] = new int[1]; // 第2行1列// 填充数据for (int i = 0; i < irregular.length; i++) {for (int j = 0; j < irregular[i].length; j++) {irregular[i][j] = i + j;}}// 打印不规则数组System.out.println("不规则二维数组:");for (int[] row : irregular) {System.out.println(Arrays.toString(row));}// 应用:杨辉三角(前5行)int[][] yanghui = new int[5][];for (int i = 0; i < yanghui.length; i++) {yanghui[i] = new int[i + 1]; // 第i行有i+1个元素yanghui[i][0] = 1; // 每行第一个元素为1yanghui[i][i] = 1; // 每行最后一个元素为1// 填充中间元素(i>1时)for (int j = 1; j < i; j++) {yanghui[i][j] = yanghui[i - 1][j - 1] + yanghui[i - 1][j];}}System.out.println("\n杨辉三角:");for (int[] row : yanghui) {System.out.println(Arrays.toString(row));}}
}
运行结果
5.4 小结
本章主要学习了 Java 数组的核心知识,包括:
一维数组:
- 定义与初始化(静态 / 动态)
- 增强 for 循环遍历
- 数组复制(
System.arraycopy()
、Arrays.copyOf()
) - 数组作为参数和返回值,可变参数方法
Arrays 工具类:
- 排序(
sort()
)、查找(binarySearch()
) - 复制(
copyOf()
、copyOfRange()
) - 填充(
fill()
)、比较(equals()
、deepEquals()
)
- 排序(
二维数组:
- 定义与初始化(规则 / 不规则)
- 元素访问与遍历
- 矩阵乘法等实际应用
数组是 Java 中处理批量数据的基础结构,掌握数组操作是学习集合、算法的前提。实际开发中需注意数组索引越界、空指针等异常,合理使用Arrays
类简化代码。
编程练习
练习 1:数组元素求和与平均值
编写方法计算数组所有元素的和与平均值。
import java.util.Arrays; // 添加Arrays导入
/*** 数组求和与平均值练习*/
public class ArraySumAvg {public static void main(String[] args) {double[] numbers = {1.5, 2.5, 3.5, 4.5, 5.5};double[] result = calculateSumAndAvg(numbers);System.out.println("数组元素:" + Arrays.toString(numbers));System.out.println("总和:" + result[0]);System.out.println("平均值:" + result[1]);}/*** 计算数组的总和与平均值* @param arr 输入数组* @return 长度为2的数组,[0]是总和,[1]是平均值*/public static double[] calculateSumAndAvg(double[] arr) {if (arr == null || arr.length == 0) {return new double[]{0, 0}; // 空数组返回0}double sum = 0;for (double num : arr) {sum += num;}double avg = sum / arr.length;return new double[]{sum, avg};}
}
练习 2:查找数组最大值与索引
编写方法查找数组中的最大值及其所有索引。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/*** 查找数组最大值与索引练习*/
public class FindMaxIndex {public static void main(String[] args) {int[] arr = {5, 3, 8, 8, 2, 8, 7};int max = findMax(arr);List<Integer> indices = findMaxIndices(arr, max);System.out.println("数组:" + Arrays.toString(arr));System.out.println("最大值:" + max);System.out.println("最大值索引:" + indices);}// 查找数组最大值public static int findMax(int[] arr) {if (arr == null || arr.length == 0) {throw new IllegalArgumentException("数组不能为空!");}int max = arr[0];for (int num : arr) {if (num > max) {max = num;}}return max;}// 查找最大值的所有索引public static List<Integer> findMaxIndices(int[] arr, int max) {List<Integer> indices = new ArrayList<>();for (int i = 0; i < arr.length; i++) {if (arr[i] == max) {indices.add(i);}}return indices;}
}
练习 3:二维数组转置
将 m×n 的矩阵转置为 n×m 的矩阵(行变列,列变行)。
import java.util.Arrays;/*** 二维数组转置练习*/
public class MatrixTranspose {public static void main(String[] args) {int[][] matrix = {{1, 2, 3},{4, 5, 6}};System.out.println("原矩阵(2×3):");printMatrix(matrix);int[][] transposed = transpose(matrix);System.out.println("\n转置后矩阵(3×2):");printMatrix(transposed);}/*** 矩阵转置* @param matrix 原矩阵(m×n)* @return 转置后的矩阵(n×m)*/public static int[][] transpose(int[][] matrix) {if (matrix == null || matrix.length == 0) return null;int m = matrix.length; // 原矩阵行数int n = matrix[0].length; // 原矩阵列数int[][] result = new int[n][m]; // 转置后n行m列for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {result[j][i] = matrix[i][j]; // 行变列,列变行}}return result;}// 打印矩阵public static void printMatrix(int[][] matrix) {for (int[] row : matrix) {System.out.println(Arrays.toString(row));}}
}
结语
数组是 Java 编程中不可或缺的数据结构,本章通过理论讲解和实战案例,详细介绍了数组的创建、使用、工具类及二维数组的应用。希望通过本文的学习,你能熟练掌握数组操作,并能在实际开发中灵活运用。后续章节将学习更复杂的集合框架,数组知识是其重要基础,建议多动手练习巩固哦!
如果有任何问题或建议,欢迎在评论区留言交流~