数组
是一种容器,用来存储(同种数据类型)的多个值。
1. 数组定义格式
- 格式
//数组类型变量的声明方式1:
数据类型[] 数组名;
//数组乐行变量的声明方式2:
数据类型 数组名[];
- 代码演示
//声明一个用来存放int类型数据的数组
int[] arrs;
//或
int arrs[];
//声明一个用来存放double类型数据的数组
double[] nums;
//或
double nums[];
//声明一个用来存放String类型数据的数组
String[] strs;
//或
String strs[];
//注意:数组类型变量和基本数据类型的变量一样,都必须先初始化,才能使用
2. 数组的动态初始化
- 初始化:就是在内存中,为数组容器开辟空间,并将数据存入容器中的过程
- 动态初始化:初始化时只指定数组长度,由系统为数组分配初始值
- 格式
//格式
数据类型[] 变量名= new 数据类型[数组长度];
//范例
int[] arr= new int[3];
- 代码演示
//案例:
//利用数组的冬天初始化,创建一个int类型的数组,可以存放5个int类型的值
int[] arr=new int[5];
//同上,创建一个可以存放3个byte类型的数组
byte[] bts=new byte[3];
//分别打印这两个数组
System.out.println(arr); //结果:[I@10f87f48
System.out.println(bts); //结果:[B@b4c966a
//直接打印数组,无法获取数组中的数据
//打印的值是该数组容器的内存地址值
/**
* [:代表数组
* I:代表是int类型
* @:分隔符
* 10f87f48:16进制内存地址值
*/
3. 数组元素访问
-
索引
-
索引是数组中空间的编号
- 索引从0开始
- 索引是连续的
- 索引逐一增加,每次加1
- 最大的索引值是数组长度减1
-
作用:访问数组容器中的空间位置
-
-
代码演示
//访问数组内部存储的数据:通过索引访问
//数组名[索引]
//代码演示:取数据
//动态初始化一个长度为5的int类型数组
int[] arr=new int[5];
//访问该数组中索引为3的位置的数据
System.out.println(arr[3]);//结果:0
//访问int数组中索引为5的位置的数组
System.out.println(arr[5]);//运行错误,因为数组长度是5,索引最大只能到4
//动态初始化一个String类型的数组,长度为3
String[] strs=new String[3];
System.out.println(strs[2]);//结果:null
//总结
/**
* 初始化数组之后,哪怕没有给数组存数据,系统也会默认给数组分配初始值。
* 基本数组类型:
* 整数类型的数组,初始化值是0;
* 小数类型的数组,初始化值是0.0;
* 字符类型的数组,初始化值是' ';
* 布尔类型的数组,初始化值是false
*
* 引用数据类型:
* 初始化值是null
* 了解:如果是数组类型的数组,那初始化值就是一个地址值
*/
//代码演示:存数据
//数组名[索引]=数据值;
//套用格式
arr[0]=2;
arr[3]=4;
System.out.println(arr[0]);//结果:2
System.out.println(arr[3]);//结果:4
4. 一个数组内存图
- 栈内存:方法运行时,进入的内存,局部变量都存放于这块内存中
- 堆内存:new出来的内容都会进入堆内存,并且会存在地址值
- 方法区:字节码文件(.class文件)加载时进入的内存
- 本地方法栈:调用操作系统相关资源
- 寄存器:交给CPU去使用
5. 两个数组内存图
int[] arr1 = new int[2];
System.out.println(arr1);
arr1[0] = 11;
arr1[1] = 22;
System.out.println(arr1[0]);
System.out.println(arr1[1]);
System.out.println("---------------");
int[] arr2 = new int[3];
System.out.println(arr2);
arr1[0] = 33;
arr1[1] = 44;
arr1[2] = 55;
System.out.println(arr1[0]);
System.out.println(arr1[1]);
System.out.println(arr1[2]);
6. 多个数组指向相同内存图
int[] arr1 = new int[2];
arr1[0] = 11;
arr1[1] = 22;
int[] arr2 = arr1;
arr1[0] = 33;
System.out.println(arr1[0]);
System.out.println(arr1[1]);
System.out.println("---------------");
System.out.println(arr2[0]);
System.out.println(arr2[1]);
7. 数组的静态初始化
-
静态初始化:初始化时指定每个数组元素的初始值,由系统决定数组长度
-
格式范例
//完整格式
//数据类型[] 数组名=new 数据类型[]{数据1,数据2,数据3,...,数据n};
//简化格式
//数据类型[] 数组名={数据1,数据2,数据3,...,数据n};
//完整格式范例
int[] arr = new int[]{23, 14, 9};
System.out.println(arr[0]);//结果:23
System.out.println(arr[1]);//结果:14
System.out.println(arr[2]);//结果:9
//简化格式范例
int[] arr2 = {66,88};
System.out.println(arr[0]);//结果:66
System.out.println(arr[1]);//结果:88
-
两种初始化的使用场景
-
动态初始化:只明确元素个数,不明确具体数值,推荐使用动态初始化。
- 要存的数据,在创建数组前还不知道是什么,比如需要键盘录入的数据。只知道要录入几个。
-
静态初始化:需求中已经明确了要操作的具体数据,直接静态初始化即可
- 要存的数据,在数组创建的时候已经有了,比如将全班学员的成绩存入数组
-
8. 数组操作的两个常见问题
- 索引越界异常:访问了数组中不存在的索引,造成索引越界异常
public class Demo01 {
public static void main(String[] args) {
int[] arr = new int[]{23, 14, 9};
System.out.println(arr[3]);
}
}
- 空指针异常:访问的数组已经不再指向堆内存的数据,造成空指针异常
- null:空值,代表不存在。表示不指向任何有效对象。
public class Demo01 {
public static void main(String[] args) {
int[] arr = new int[]{23, 14, 9};
System.out.println(arr[1]);
arr = null;
System.out.println(arr[1]);
}
}
## 9. 数组遍历
- 格式
```java
//数组定义及初始化
int[] arr={......};
//...
//遍历数组
for(int i=0;i<arr.length;x++){
//arr[i],获取到的就是数组对应索引为i的数据
//由于i的值从0开始,逐一增加,所以每次循环就能获得一个数组数据,循环结束,数组数据也都拿了一遍
// arr[i];
//至于拿出来的数据是直接打印,还是用一个变量接收,用作后面使用,完全看需求决定
}
- 注意
- 遍历数组,是指取出数组中所有数据的一个过程,不能局限理解为就是打印数组数据
10. 数组获取最大值
求最值的思路:
1.假设数组中的0索引元素为最大值max(擂主)
2.让其他的元素和max比较,把较大的值赋值给max(打赢的站在擂台上)
3.最终max就是最大值(最后站在擂台上的就是最大值)
//案例:求数组中的最小值,并打印
//定义一个数组,静态初始化
int[] arr={1,3,46,8,2,5,9,7};
//1.假设数组中的0索引元素为最小值(擂主)
int min=arr[0];
//2.让其他的元素和min比较,把较小的值赋值给min(打赢的站在擂台上)
for (int i = 1; i < arr.length; i++) {
if(arr[i]<min){
//3.arr[i]比上一个小一点的守擂的min还要小,所以就让arr[i]去守擂
min=arr[i]; //打赢的站在擂台上
}
}
//4.最终min就是最小值(最后站在擂台上的就是最小值)
System.out.println("最小值为:"+min);
11. 数组元素求和
-
需求:键盘录入5个整数,存储到数组中,并对数组求和
-
思路
- 创建键盘录入对象,准备键盘录入数字
- 定义一个求和变量,准备记录累加后的值
- 动态初始化一个长度为5的int数组,准备存储键盘录入的数据
- 将键盘录入的数值存储到数组中
- 遍历数组,取出每一个元素,并求和
- 输出总和
-
代码演示
//1.创建键盘录入对象,准备键盘录入数字
Scanner sc = new Scanner(System.in);
//2.定义一个求和变量,准备记录累加后的值
int sum = 0;
//3.动态初始化一个长度为5的int数组,准备存储键盘录入的数据
int[] arr = new int[5];
//4.由于数组有多长录入几次,就是遍历数组录入
for (int i = 0; i < arr.length; i++) {
//5.提示用户录入数字
System.out.println("请录入一个整数:");
int num = sc.nextInt();
//6.将键盘录入的数值存储到数组中,
arr[i] = num;
}
//7.遍历数组,求和
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
//8.输出总和
System.out.println("数组中所有元素的和是:"+sum);
12. 数组基本查找
-
需求:已知一个数组==arr = {19,28,37,46,50};==键盘录入一个数据,查找该数据在数组中的索引,并在控制台输出找到的索引值
-
分析思路
- 分析:
- 键盘录入一个数据后,让这个数据和数组中的每一个元素进行比较,如果数据值相等,返回该数据值对应的索引即可。
- 但是,加入录入了一个数组中不存在的数据,这个时候,就没有任何内容输出了,很明显是有问题的,在实际开发中,如果对应的索引不存在,我们一般都是返回一个负数,而且经常用-1来标识。
- 分析:
-
思路:
-
代码演示
int[] array={10,20,30,40,15,60,15,80};
//1.键盘录入需要查找的元素
Scanner sc=new Scanner(System.in);
//提示用户录入数据
System.out.println("请录入需要查找的数据:");
int key=sc.nextInt();
int index=-1; //记录查找的索引,规定-1表示没有找到元素
//2.遍历数组中的元素和key进行比较
for (int i = 0; i < array.length; i++) {
if(array[i]==key){
index=i;
//一旦找到了,后面的数据就不需要再遍历了,直接结束循环即可
break;
}
}
//判断index的值,是否等于-1
if(index==-1){
System.out.println("对不起,没有这个元素");
}else{
System.out.println(key+"元素在数组中的索引为:"+index);
}
13. 评委打分
- 需求
- 思路
- 代码实现
//1.定义数组,用于存储评委的分数
int[] array=new int[6];
//2.循环的采用键盘录入的方式,代表评委打分
Scanner sc=new Scanner(System.in);
for (int i = 0; i < array.length; i++) {
//2.1 提示用户录入分数
System.out.println("请输入第"+(i+1)+"评委的分数:");
int num = sc.nextInt();
//2.2 把分数存入数组中
array[i]=num;
}
//3.求数组元素的最大值
//3.1 把数组中的0索引元素假设为最大值
int max=array[0];
for (int i = 1; i < array.length; i++) {
//3.2 把数组中元素较大的值赋值给max
if(array[i]>max){
max=array[i];
}
}
System.out.println("最大值为:"+max);
//4.求数组元素的最小值
int min=array[0];
for (int i = 1; i < array.length; i++) {
//4.1 把数组中元素较小的值赋值给min
if(array[i]<min){
min=array[i];
}
}
System.out.println("最小值为:"+min);
//5.求数组元素的和
int sum=0;
for (int i = 0; i < array.length; i++) {
sum+=array[i];
}
System.out.println("所有元素的和为:"+sum);
//6.求平均值
double avg=(sum-max-min)*1.0/(array.length-2);
System.out.println("最终得分:"+avg);
二维数组
1. 概述
- 概述:二维数组也是一种容器,不同于一维数组,该容器存储的都是一维数组容器
- 为什么要有二维数组:
- 假设给一个学校做一个学生管理系统,该学校有6个年级,每个年级10跟班,每个班60个学生。需要用数组存放这些学生的数据
- 如果我们把这些学生数据存放在一个数组里面,这个数组的数据过于庞大,你要到里面找对应学生的成绩会很困难
- 如果一个班级成绩装一个数组,通过班级去找学生,会简单一点
- 但是这些数组如果不统一管理,还要判断学生是哪个年级
- 所以如果用一个长度为6的数组,每个索引位置存放一个年纪的数据,那管理起来就很方便了
- 比如我要找3年级2班的张三成绩,那就是先找到三年级,再找到2班,然后再到2班里面去遍历出张三的成绩
2. 动态初始化
//格式1:数据类型[][] 变量名 = new 数据类型[m][n];
//m表示这个二维数组,可以存放多少个一维数组。n表示每一个一维数组,可以存放多少个元素
int[][] arr = new int[2][3];
System.out.println(arr);//结果:[[I@10f87f48
System.out.println(arr[0]);//结果:[I@b4c966a
System.out.println(arr[1]);//结果:[I@2f4d3709
//以上结果表明,二维数组中存储的数据还是数组,所以打印的就是地址值
System.out.println(arr[0][0]);//结果:0
System.out.println(arr[0][1]);//结果:0
System.out.println(arr[0][2]);//结果:0
//以上结果表明,二维数组中存储的是一维数组,可以通过二维数组和一维数组的索引拿到存储的数据值
//可以存值,就可以赋值
arr[1][0] = 11;
arr[1][1] = 22;
arr[1][2] = 33;
3. 访问元素的细节问题
int[] arr1 = {11, 22, 33};
int[] arr2 = {44, 55, 66};
int[] arr3 = {77, 88, 99, 100};
int[][] arr = new int[3][3];
//此时二维数组索引2位置指向的数组是一个长度为3的数组,此时给该数组索引为3的位置赋值会索引越界
arr[2][3] = 101;
arr[0] = arr1;
arr[1] = arr2;
//通过赋值操作,让原本指向长度为3的数组指向了一个长度为4的数组,该数组索引最大值是3
arr[2] = arr3;
//由于已经更换了指向的数组,所以可以通过二维索引3找到对应的值
System.out.println(arr[2][3]);
4. 静态初始化
//格式:数据类型[][] 变量名={{元素1,元素2,...},{元素1,元素2,...},...};
//范例:int[][] arr={{11,22},{33,44}};
//代码案例
int[] arr1 = {11, 22, 33};
int[] arr2 = {44, 55, 66};
int[][] arr = {{11, 22, 33}, {44, 55, 66}};
System.out.println(arr[0][1]);
int[][] array = {arr1, arr2};//结果:22
System.out.println(arr[1][0]);//结果:44
5. 案例:遍历
-
需求:已知一个二维数组arr = {{11, 22, 33}, {33, 44, 55,}};遍历该数组,取出所有元素并打印
-
代码实现
int[][] arr = {{11, 22, 33}, {33, 44, 55,}};
//1.先遍历二维数组,把里面的一维数组拿出来
for (int i = 0; i < arr.length; i++) {
//2.根据拿出的一维数组,再遍历这个一维数组
for (int j = 0; j < arr[i].length; j++) {
//3.打印对应一维数组中的值
System.out.println(arr[i][j]);
}
}
6. 案例:求和
- 需求:某公司季度和月份统计的数据如下:单位(万元)
- 第一季度:22 , 66 , 44
- 第二季度:77 , 33 , 88
- 第三季度:25 , 45 , 65
- 第四季度:11 , 66 , 99
- 思路:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-py25M28O-1654673859069)(day04.assets/1620031824874.png)]
- 代码实现
//1.定义求和变量,准备记录最终累加结果
int sum = 0;
//2.使用二维数组来存储数据,每个季度是一个一维数组,再将4个一维数组装起来
int[][] arr = {{22, 66, 44}, {77, 33, 88}, {25, 45, 65}, {11, 66, 99}};
//3.遍历二维数组,取出所有元素,累加求和
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
sum += arr[i][j];
}
}
//4.打印最终累加结果
System.out.println(sum);
}
}
)