4. 一维数组的应用
**案例1:**升景坊单间短期出租4个月,550元/月(水电煤公摊,网费35元/月),空调、卫生间、厨房齐全。屋内均是IT行业人士,喜欢安静。所以要求来租者最好是同行或者刚毕业的年轻人,爱干净、安静。
public class ArrayTest { public static void main(String[] args) { int[] arr = new int[]{8,2,1,0,3}; int[] index = new int[]{2,0,3,2,4,0,1,3,2,3,3}; String tel = ""; for(int i = 0;i < index.length;i++){ tel += arr[index[i]]; } System.out.println("联系方式:" + tel); } }
案例2:输出英文星期几
用一个数组,保存星期一到星期天的7个英语单词,从键盘输入1-7,显示对应的单词
{“Monday”,“Tuesday”,“Wednesday”,“Thursday”,“Friday”,“Saturday”,“Sunday”}
import java.util.Scanner; /** * @author 尚硅谷-宋红康 * @create 14:37 */ public class WeekArrayTest { public static void main(String[] args) { //1. 声明并初始化星期的数组 String[] weeks = {"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"}; //2. 使用Scanner从键盘获取1-7范围的整数 Scanner scanner = new Scanner(System.in); System.out.println("请输入[1-7]范围的整数:"); int number = scanner.nextInt(); if(number < 1 || number > 7){ System.out.println("你输入的输入非法"); }else{ //3. 根据输入的整数,到数组中相应的索引位置获取指定的元素(即:星期几) System.out.println("对应的星期为:" + weeks[number - 1]); } scanner.close(); } }
**案例3:**从键盘读入学生成绩,找出最高分,并输出学生成绩等级。
- 成绩>=最高分-10 等级为’A’
- 成绩>=最高分-20 等级为’B’
- 成绩>=最高分-30 等级为’C’
- 其余 等级为’D’
提示:先读入学生人数,根据人数创建int数组,存放学生成绩。
/** * @author 尚硅谷-宋红康 * @create 14:55 */ public class ScoreTest1 { public static void main(String[] args) { //1. 根据提示,获取学生人数 System.out.print("请输入学生人数:"); Scanner scanner = new Scanner(System.in); int count = scanner.nextInt(); //2. 根据学生人数,创建指定长度的数组 (使用动态初始化) int[] scores = new int[count]; //3. 使用循环,依次给数组的元素赋值 int maxScore = 0; //记录最高分 System.out.println("请输入" + count + "个成绩"); for (int i = 0; i < scores.length; i++) { scores[i] = scanner.nextInt(); //4. 获取数组中元素的最大值,即为最高分 if(maxScore < scores[i]){ maxScore = scores[i]; } } System.out.println("最高分是:" + maxScore); //5. 遍历数组元素,输出各自的分数,并根据其分数与最高分的差值,获取各自的等级 char grade; for (int i = 0; i < scores.length; i++) { if(scores[i] >= maxScore - 10){ grade = 'A'; }else if(scores[i] >= maxScore - 20){ grade = 'B'; }else if(scores[i] >= maxScore - 30){ grade = 'C'; }else{ grade = 'D'; } System.out.println("student " + i + " socre is " + scores[i] + ", grade is " + grade); } //关闭资源 scanner.close(); } }
5. 多维数组的使用
5.1 概述
- Java 语言里提供了支持多维数组的语法。
- 如果说可以把一维数组当成几何中的
线性图形
,那么二维数组就相当于是一个表格
,像Excel中的表格、围棋棋盘一样。
应用举例1:
某公司2022年全年各个月份的销售额进行登记。按月份存储,可以使用一维数组。如下:
int[] monthData = new int[]{23,43,22,34,55,65,44,67,45,78,67,66};
如果改写为按季度
为单位存储怎么办呢?
int[][] quarterData = new int[][]{{23,43,22},{34,55,65},{44,67,45},{78,67,66}};
- 应用举例2:
高一年级三个班级均由多个学生姓名构成一个个数组。如下:
String[] class1 = new String[]{"段誉","令狐冲","任我行"}; String[] class2 = new String[]{"张三丰","周芷若"}; String[] class3 = new String[]{"赵敏","张无忌","韦小宝","杨过"};
那从整个年级看,我们可以声明一个二维数组。如下:
String[][] grade = new String[][]{{"段誉","令狐冲","任我行"},{"张三丰","周芷若"},{"赵敏","张无忌","韦小宝","杨过"}};
- 应用举例3:
蓝框的几个元素,可以使用一维数组来存储。但现在发现每个元素下还有下拉框,其内部还有元素,那就需要使用二维数组来存储:
- 使用说明
- 对于二维数组的理解,可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。
- 其实,从数组底层的运行机制来看,其实没有多维数组。
5.2 声明与初始化
5.2.1 声明
二维数组声明的语法格式:
//推荐 元素的数据类型[][] 二维数组的名称; //不推荐 元素的数据类型 二维数组名[][]; //不推荐 元素的数据类型[] 二维数组名[];
例如:
public class Test20TwoDimensionalArrayDefine { public static void main(String[] args) { //存储多组成绩 int[][] grades; //存储多组姓名 String[][] names; } }
面试:
int[] x, y[]; //x是一维数组,y是二维数组
5.2.2 静态初始化
格式:
int[][] arr = new int[][]{{3,8,2},{2,7},{9,0,1,6}};
定义一个名称为arr的二维数组,二维数组中有三个一维数组
- 每一个一维数组中具体元素也都已初始化
- 第一个一维数组 arr[0] = {3,8,2};
- 第二个一维数组 arr[1] = {2,7};
- 第三个一维数组 arr[2] = {9,0,1,6};
- 第三个一维数组的长度表示方式:arr[2].length;
- 注意特殊写法情况:int[] x,y[]; x是一维数组,y是二维数组。
- 举例1:
int[][] arr = {{1,2,3},{4,5,6},{7,8,9,10}};//声明与初始化必须在一句完成 int[][] arr = new int[][]{{1,2,3},{4,5,6},{7,8,9,10}}; int[][] arr; arr = new int[][]{{1,2,3},{4,5,6},{7,8,9,10}}; arr = new int[3][3]{{1,2,3},{4,5,6},{7,8,9,10}};//错误,静态初始化右边new 数据类型[][]中不能写数字
- 举例2:
public class TwoDimensionalArrayInitialize { public static void main(String[] args) { //存储多组成绩 int[][] grades = { {89,75,99,100}, {88,96,78,63,100,86}, {56,63,58}, {99,66,77,88} }; //存储多组姓名 String[][] names = { {"张三","李四", "王五", "赵六"}, {"刘备","关羽","张飞","诸葛亮","赵云","马超"}, {"曹丕","曹植","曹冲"}, {"孙权","周瑜","鲁肃","黄盖"} }; } }
5.2.3 动态初始化
如果二维数组的每一个数据,甚至是每一行的列数,需要后期单独确定,那么就只能使用动态初始化方式了。动态初始化方式分为两种格式:
格式1:规则二维表:每一行的列数是相同的
//(1)确定行数和列数 元素的数据类型[][] 二维数组名 = new 元素的数据类型[m][n]; //其中,m:表示这个二维数组有多少个一维数组。或者说一共二维表有几行 //其中,n:表示每一个一维数组的元素有多少个。或者说每一行共有一个单元格 //此时创建完数组,行数、列数确定,而且元素也都有默认值 //(2)再为元素赋新值 二维数组名[行下标][列下标] = 值;
举例:
int[][] arr = new int[3][2];
- 定义了名称为arr的二维数组
- 二维数组中有3个一维数组
- 每一个一维数组中有2个元素
- 一维数组的名称分别为arr[0], arr[1], arr[2]
- 给第一个一维数组1脚标位赋值为78写法是:
arr[0][1] = 78;
格式2:不规则:每一行的列数不一样
//(1)先确定总行数 元素的数据类型[][] 二维数组名 = new 元素的数据类型[总行数][]; //此时只是确定了总行数,每一行里面现在是null //(2)再确定每一行的列数,创建每一行的一维数组 二维数组名[行下标] = new 元素的数据类型[该行的总列数]; //此时已经new完的行的元素就有默认值了,没有new的行还是null //(3)再为元素赋值 二维数组名[行下标][列下标] = 值;
举例:
int[][] arr = new int[3][];
- 二维数组中有3个一维数组。
- 每个一维数组都是默认初始化值null (注意:区别于格式1)
- 可以对这个三个一维数组分别进行初始化:arr[0] = new int[3]; arr[1] = new int[1]; arr[2] = new int[2];
- 注:
int[][]arr = new int[][3];
//非法
练习:
/* 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 */ public class Test25DifferentElementCount { public static void main(String[] args){ //1、声明一个二维数组,并且确定行数 //因为每一行的列数不同,这里无法直接确定列数 int[][] arr = new int[5][]; //2、确定每一行的列数 for(int i=0; i<arr.length; i++){ /* arr[0] 的列数是1 arr[1] 的列数是2 arr[2] 的列数是3 arr[3] 的列数是4 arr[4] 的列数是5 */ arr[i] = new int[i+1]; } //3、确定元素的值 for(int i=0; i<arr.length; i++){ for(int j=0; j<arr[i].length; j++){ arr[i][j] = i+1; } } //4、遍历显示 for(int i=0; i<arr.length; i++){ for(int j=0; j<arr[i].length; j++){ System.out.print(arr[i][j] + " "); } System.out.println(); } } }
5.3 数组的长度和角标
- 二维数组的长度/行数:二维数组名.length
- 二维数组的某一行:二维数组名[行下标],此时相当于获取其中一组数据。它本质上是一个一维数组。行下标的范围:[0, 二维数组名.length-1]。此时把二维数组看成一维数组的话,元素是行对象。
- 某一行的列数:二维数组名[行下标].length,因为二维数组的每一行是一个一维数组。
- 某一个元素:二维数组名[行下标][列下标],即先确定行/组,再确定列。
public class Test22TwoDimensionalArrayUse { public static void main(String[] args){ //存储3个小组的学员的成绩,分开存储,使用二维数组。 /* int[][] scores1; int scores2[][]; int[] scores3[];*/ int[][] scores = { {85,96,85,75}, {99,96,74,72,75}, {52,42,56,75} }; System.out.println(scores);//[[I@15db9742 System.out.println("一共有" + scores.length +"组成绩."); //[[:代表二维数组,I代表元素类型是int System.out.println(scores[0]);//[I@6d06d69c //[:代表一维数组,I代表元素类型是int System.out.println(scores[1]);//[I@7852e922 System.out.println(scores[2]);//[I@4e25154f //System.out.println(scores[3]);//ArrayIndexOutOfBoundsException: 3 System.out.println("第1组有" + scores[0].length +"个学员."); System.out.println("第2组有" + scores[1].length +"个学员."); System.out.println("第3组有" + scores[2].length +"个学员."); System.out.println("第1组的每一个学员成绩如下:"); //第一行的元素 System.out.println(scores[0][0]);//85 System.out.println(scores[0][1]);//96 System.out.println(scores[0][2]);//85 System.out.println(scores[0][3]);//75 //System.out.println(scores[0][4]);//java.lang.ArrayIndexOutOfBoundsException: 4 } }
5.4 二维数组的遍历
- 格式:
for(int i=0; i<二维数组名.length; i++){ //二维数组对象.length for(int j=0; j<二维数组名[i].length; j++){//二维数组行对象.length System.out.print(二维数组名[i][j]); } System.out.println(); }
- 举例:
public class Test23TwoDimensionalArrayIterate { public static void main(String[] args) { //存储3个小组的学员的成绩,分开存储,使用二维数组。 int[][] scores = { {85,96,85,75}, {99,96,74,72,75}, {52,42,56,75} }; System.out.println("一共有" + scores.length +"组成绩."); for (int i = 0; i < scores.length; i++) { System.out.print("第" + (i+1) +"组有" + scores[i].length + "个学员,成绩如下:"); for (int j = 0; j < scores[i].length; j++) { System.out.print(scores[i][j]+"\t"); } System.out.println(); } } }
5.5 内存解析
二维数组本质上是元素类型是一维数组的一维数组。
int[][] arr = { {1}, {2,2}, {3,3,3}, {4,4,4,4}, {5,5,5,5,5} };
//1、声明二维数组,并确定行数和列数 int[][] arr = new int[4][5]; //2、确定元素的值 for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr.length; j++) { arr[i][j] = i + 1; } }
//1、声明一个二维数组,并且确定行数 //因为每一行的列数不同,这里无法直接确定列数 int[][] arr = new int[5][]; //2、确定每一行的列数 for(int i=0; i<arr.length; i++){ /* arr[0] 的列数是1 arr[1] 的列数是2 arr[2] 的列数是3 arr[3] 的列数是4 arr[4] 的列数是5 */ arr[i] = new int[i+1]; } //3、确定元素的值 for(int i=0; i<arr.length; i++){ for(int j=0; j<arr[i].length; j++){ arr[i][j] = i+1; } }
5.6 应用举例
**案例1:**获取arr数组中所有元素的和。
提示:使用for的嵌套循环即可。
**案例2:**声明:int[] x,y[]; 在给x,y变量赋值以后,以下选项允许通过编译的是:
声明:int[] x,y[]; 在给x,y变量赋值以后,以下选项允许通过编译的是: a) x[0] = y; //no b) y[0] = x; //yes c) y[0][0] = x; //no d) x[0][0] = y; //no e) y[0][0] = x[0]; //yes f) x = y; //no 提示: 一维数组:int[] x 或者int x[] 二维数组:int[][] y 或者 int[] y[] 或者 int y[][]
**案例3:**使用二维数组打印一个 10 行杨辉三角。
提示:
- 第一行有 1 个元素, 第 n 行有 n 个元素
- 每一行的第一个元素和最后一个元素都是 1
- 从第三行开始, 对于非第一个元素和最后一个元素的元素。即:
yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
/** * @author 尚硅谷-宋红康 * @create 10:11 */ public class YangHuiTest { public static void main(String[] args) { //1. 动态初始化的方式创建二维数组 int[][] yangHui = new int[10][]; for (int i = 0; i < yangHui.length; i++) { yangHui[i] = new int[i + 1]; //2. 给数组元素赋值 // 2.1 给外层数组元素中的首元素和末元素赋值 yangHui[i][0] = yangHui[i][i] = 1; //2.2 给外层数组元素中的非首元素和非末元素赋值(难) //if(i > 1){ //从 i == 2 开始执行 for(int j = 1;j < yangHui[i].length - 1;j++){ //非首元素和非末元素的角标范围 yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j]; } //} } //3. 遍历二维数组 for (int i = 0; i < yangHui.length; i++) { for (int j = 0; j < yangHui[i].length; j++) { System.out.print(yangHui[i][j] + "\t"); } System.out.println(); } } }