4 Java数组(重点)
4.1 数组介绍
4.1.1 数组是什么
- 数组就是一个容器,用来存储一批同种类型的数据。
- 例子
//存储5个整型数据 20, 10, 80, 60, 90
int[] arr = {20, 10, 80, 60, 90};
//存储3个字符串数据 牛二, 西门, 狗剩
String[] names = {"牛二", "西门", "狗剩"};
4.1.2 总结:
-
什么是数组?
- 数组是一个装数据的容器,并且要求装的数据都要是同一种类型
-
什么时候使用数组?
- 批量操作同类型数据时,建议使用数组。
-
使用数组的好处是什么?
- 使用数组可以减少代码开发,而且代码逻辑更清晰
4.2 数组的定义和访问
4.2.1 数组的静态初始化
- 数组的静态初始化
- 定义数组的时候直接给数组赋值。(这就要求在定义数组的时候就得知道要存的元素)
- 静态初始化数组的格式:
// 完整格式 // 数据类型[] 数据名=new 数据类型[]{元素1,, 元素2, 元素3...}; int[] ages=new int[]{23, 25, 34, 23, 35}; double[] scores = new double[]{89.9, 99.5, 59.5, 88.0}; //简化格式 // 数据类型[] 数据名={元素1, 元素2, 元素3...}; int[] ages={23, 25, 34, 23, 35};
- 注意
- “数据类型[] 数组名”也可写成 “数据类型 数组名[] ”。
- 什么类型的数组只能存放什么类型的数据。
- 总结
- 数组的静态初始化写法是什么样的?
//简化格式
数据类型[] 数组名 = { 元素1,元素2 ,元素3,… };
int[] ages = {12, 24, 36, 48, 60};
// 完整格式
数据类型[] 数组名 = new 数据类型[]{ 元素1,元素2 ,元素3… };
int[] ages = new int[]{12, 24, 36, 48, 60};
- 定义数组的时候的两个注意点是什么?
- 数据类型[] 数组名 也可写成 数据类型 数组名[]
- 什么类型的数组必须存放什么类型的数据
- 数组在计算机中的基本原理
int[] ages = {12, 24, 36};
int[] ages = new int[]{12, 24, 36};
- 注意:数组变量名中存储的是数组在内存中的地址,数组是一种引用数据类型。
- 基本数据类型: 四类八种, 变量记录的就是数据本身
- 引用数据类型: 变量记录的是内存地址, 该变量对应的类型就是引用数据类型
- 总结
- 数组是属于什么类型,数组变量名中存储的是什么?
- 数组是引用数据类型
- 数组变量名中存储的是数组在内存中的地址信息
- 在数组中,索引是用来做什么的?
- 索引,又叫下标,是指一个数据元素在数组里面排在第几个的位置
- 索引是是从0开始计数的
- 数组是属于什么类型,数组变量名中存储的是什么?
4.2.2 数组的访问
- 数组名[索引]
int[] arr={12, 24,36};
System.out.println("arr[0]");
arr[2]=100;
System.out.println(arr[2]); // 100
- 数组的长度属性:length
// 获取数组的长度(就是数组元素的个数)
System.out.println(arr.length); // 3
- 问题:数组的最大索引可以怎么表示?
- 数组名. length – 1 // 前提:元素个数大于0
- 总结
-
如何访问数组的元素?
- 数组名称[索引]
-
如何访问数组的长度?
- 数组名称.length
-
数组的最大索引是多少?
- 数组名. length – 1 // 前提:元素个数大于0
-
如果访问数组时,使用的索引超过了数组最大索引会出什么问题?
- 出现一个索引越界(ArrayIndexOutOfBoundsException)的异常提示。
4.2.3 数组的遍历
- 什么是遍历
- 遍历:就是一个一个数据的访问。
int[] ages = {20, 30, 40, 50};
for (int i = 0; i < ages.length; i++) {
System.out.println(ages[i]);
}
- 为什么要遍历数组?
- 求和, 元素搜索, 找最大值, 找最小值
- 总结:
- 什么是遍历?
- 一个一个的访问容器里面的数据.
int[] ages = {20, 30, 40, 50}; for (int i = 0; i < ages.length; i++) { System.out.println(ages[i]); }
- 案例: 数组遍历-求和
- 需求:
- 某部门5名员工的销售额分别是:16、26、36、6、100,请计算出他们部门的总销售额。
- 分析:
- 把这5个数据拿到程序中去 —> 使用数组
int[] money = {16, 26, 36, 6, 100};
- 遍历数组,获取到数组中的每个数据
- 然后在外面定义求和变量把他们累加起来。
- 完整代码:
package com.itheima.a_define;
/**
* @author: LXHYouth
* @date: 2024/3/6 11:10
* @Version: 1.0
* @Description 计算销售总额
*/
public class Demo04 {
public static void main(String[] args) {
double sum=0;
int[] sales={16, 26, 36, 6, 100};
for (int i = 0; i < sales.length; i++) {
sum+=sales[i];
}
System.out.println("部门的总销售额为: "+sum);
System.out.println("平均销售额为: "+(sum/sales.length));
}
}
4.2.4 动态初始化数组
- 创建数组时不知道里面的数据
- 数组的动态初始化
- 定义数组时先不存入具体的元素值,只确定数组存储的数据类型和数组的长度
- 数组的动态初始化格式:
数据类型[] 数组名 = new 数据类型[长度];
int[] arr = new int[3];
// 后赋值
arr[0] = 10;
System.out.println(arr[0]); // 10
温馨提示:
静态初始化和动态初始化数组的写法是独立的,不可以混用.int[] arr = new int[3]{30,40,50};(错误示范)
- 动态初始化数组元素默认值规则:
数据类型 | 明细 | 默认值 |
---|---|---|
基本类型 | byte、short、char、int、long | 0 |
基本类型 | float、double | 0.0 |
基本类型 | boolean | false |
引用类型 | 类、接口、数组、String | null |
- 总结
-
动态初始化数组的写法是什么样的?
数据类型[] 数组名 = new 数据类型[长度]; int[] ages = new int[4];
-
动态初始化数组后元素的默认值是什么样的?
- byte、short、int 、char、long类型数组的元素默认值都是0
- float、double类型数组元素的默认值都是0.0
- boolean类型数组的元素默认值是false
- 引用数据类型数组的元素的默认值是null
-
两种数组定义的方法各自适合什么业务场景?
- 动态初始化:开始不确定具体元素值,只知道元素个数
- 静态初始化:一开始就知道要存入哪些元素值
- 案例: 评委打分
- 需求
- 某歌唱比赛需要录入6名评委的打分(有小数),录入完毕后立即输出平均分做为选手得分。
- 分析
- 6名评委的打分是后期录入的,一开始不知道具体的分数,因此定义一个动态初始化的数组存分数。
double[] scores = new double[6];
- 遍历数组中的每个位置,每次提示用户录入一个评委的分数,并存入到数组对应的位置。
- 遍历数组中的每个元素进行求和,最终算出平均分打印出来即可。
- 6名评委的打分是后期录入的,一开始不知道具体的分数,因此定义一个动态初始化的数组存分数。
- 详细代码
package com.itheima.a_define;
import java.util.Scanner;
/**
* @author: LXHYouth
* @date: 2024/3/6 12:00
* @Version: 1.0
* @Description
*/
/*
数组案例:
某歌唱比赛需要录入6名评委的打分(有小数),录入完毕后立即输出平均分做为选手得分。
*/
public class Demo06 {
public static void main(String[] args) {
// 思路
// 动态初始化定义一个数组,长度为6
double[] scores=new double[6];
// 创建一个扫描器对象
Scanner scanner = new Scanner(System.in);
// 定义一个变量存储总分
double sum=0;
// 提示评委打分
for(int i=0;i<scores.length;i++){
System.out.print("请"+(i+1)+"号评委打分: ");
// 存储键盘输入的分值
scores[i]=scanner.nextDouble();
sum +=scores[i];
}
// 计算总分,计算平均值
double avg=sum/scores.length;
System.out.print("选手得分为: "+ avg);
}
}
4.3 数组常见案列
4.3.1 统计及格人数
- 成绩数据分析
- 需求
- 某班级学生的Java考试成绩是:99, 100, 62, 15, 48, 65, 98, 99, 5, 59.5, 75;
- 请统计及格学生总人数。
- 分析
- 把这一批成绩数据拿到程序中去 —> 使用静态初始化的数组装起来。
double[] scores = {99, 100, 62, 15, 48, ...};
- 使用for循环遍历数组中的每个成绩,并在循环外定义一个计数变量count。
- 每遍历一个数据,判断该数据是否大于等于60分,满足条件则让count 加 1。
- 完整代码
package com.itheima.b_case;
/**
* @author: LXHYouth
* @date: 2024/3/8 10:05
* @Version: 1.0
* @Description 通过考试成绩计算总人数
*/
public class Demo1 {
public static void main(String[] args) {
// 定义一个计数器
int count=0;
// 创建一个double型数组, 存储分数
double[] scores={99, 100, 62, 15, 48, 65, 98, 99, 5, 59.5, 75};
for (int i = 0; i < scores.length; i++) {
// 判断分数是否大于等于60
if(scores[i]>=60){
//大于等于60就计数
count++;
}
}
System.out.println("及格总人数为: "+ count);
}
}
4.3.2 数组求最值
- 实现步骤:
- 把数据拿到程序中去,用数组装起来。
int[] faceScores = {15, 9000, 10000, 20000, 9500, -5};
- 定义一个变量用于记录最终的最大值。
int max = faceScores[0]; // 建议存储数组的第一个元素值作为参照
-
从第二个位置开始:遍历数组的数据,如果遍历的当前数据大于max变量存储的数据,则替换变量存储的数据为当前数据。
-
循环结束后输出max变量即可。
-
完整代码(待优化)
-
优化思路: 可以使用三元运算符,来代替if语句
-
效果: 使代码看起来更简洁
package com.itheima.b_case;
/*
求最值
现有一个数组,内含元素: 15, 9000, 10000, 20000, 9500, -5
求其中的最大元素
扩展1: 能不能求其中的最小元素
扩展2: 能不能使用一个循环求其中的最大和最小元素
*/
public class Demo2 {
public static void main(String[] args) {
// 创建一个int型数组
int[] num = new int[]{15, 9000, 10000, 20000, 9500, -5};
// 定义一个int变量, 存储最大值
int max=0;
// 定义一个int变量, 存储最小值
int min=0;
for (int i = 0; i < num.length; i++) {
// 与目前最大值做对比, 大于就替换, 小于就对比下一个
if(max<num[i]){
max=num[i];
}
// 与目前最小值做对比, 小于就替换, 大于就对比下一个
// if(min>num[i]){
// min=num[i];
// }
// 使用三元运行付优化后
min=min<num[i]?min:num[i];
}
// 输出最大最小值
System.out.println("数组最大值为: "+max);
System.out.println("数组最大值为: "+min);
}
}
4.3.3 数组反转
- 需求
- 某个数组有5个数据:10,20,30,40,50,请将这个数组中的数据进行反转。
- [10, 20, 30, 40, 50] 反转后 [50, 40, 30, 20, 10]
- 分析
- 数组的反转操作实际上就是:依次前后交换数据即可实现。
- 完整代码
package com.itheima.b_case;
/**
* @author: LXHYouth
* @date: 2024/3/8 10:38
* @Version: 1.0
* @Description 数组前后数据反转
*/
public class Demo4 {
public static void main(String[] args) {
// 创建一个数组
int[] num= {10, 20, 30, 40, 50};
System.out.println("初始数组:");
for (int n = 0; n < num.length; n++) {
System.out.print(num[n]+" ");
}
// 控制换行
System.out.println();
// 定义一个变量, 实现最大索引, 根据for循环往前移
int j=num.length-1;
// 前和后两个数值进行对调
for (int i = 0; i < j; i++) {
int temp=num[i];
num[i]=num[j];
num[j]=temp;
// 控制索引向前移
j--;
}
System.out.println("字符串反转后:");
for (int n = 0; n < num.length; n++) {
System.out.print(num[n]+" ");
}
}
}
4.3.4 随机排名
-
需求
- 某公司开发部5名开发人员,要进行项目进展汇报演讲,现在采取随机排名后进行汇报。请先依次录入5名员工的工号,然后展示出一组随机的排名顺序。
-
分析
- 在程序中录入5名员工的工号存储起来 —> 使用动态初始化数组的方式。
- 依次遍历数组中的每个数据。
- 每遍历到一个数据,都随机一个索引值出来,让当前数据与该索引位置处的数据进行交换。
-
完整代码:
package com.itheima.b_case;
/**
* @author: LXHYouth
* @date: 2024/3/8 10:41
* @Version: 1.0
* @Description 打乱排名
*/
import java.util.Random;
import java.util.Scanner;
public class Demo5 {
public static void main(String[] args) {
// 创建一个数组存储5个人的工号
int[] num= new int[5];
// 创建一个扫描器对象
Scanner scanner = new Scanner(System.in);
// 定义一个计数器
int count=0;
// 循环录入工号
while(count<num.length){
System.out.print("请录入第"+(count+1)+"位工号: ");
num[count++]=scanner.nextInt();
}
// 遍历一下刚刚录入的工号
for (int i = 0; i < num.length; i++) {
System.out.println("录入的工号为:"+num[i]);
}
System.out.print("录入的工号顺序为:");
for (int i = 0; i < num.length; i++) {
System.out.print(num[i]+" ");
}
// 控制换行
System.out.println();
// 创建一个随机数对象
Random random = new Random();
// 随机一个数组下表对应的值, 与现在遍历的当前值进行对换.
for (int i = 0; i < num.length; i++) {
// 获取一个随机变量
int r=random.nextInt(num.length);
int temp= num[r];
num[r]=num[i];
num[i]=temp;
}
System.out.print("随机变换后的为:");
// 遍历一下随机变换后的工号排序
for (int i = 0; i < num.length; i++) {
System.out.print(num[i]+" ");
}
}
}
4.4 数组执行原理
4.4.1 数组的执行原理
- Java 内存分配介绍
- 数组在计算机中的执行原理
- 总结
-
运行一个Java程序,主要看JVM中包含的哪几部分内存区域?
- 方法区: 存放class文件
- 栈内存: 方法被调用后,进入栈内存,变量也存在这
- 堆内存: new出来的东西进入堆内存
-
简单说说 int a = 20; int[] arr = new int[3]这两行代码的执行原理?
- a是变量,直接放在栈中,a变量中存储的数据就是20这个值。
- new int[3]是创建一个数组对象,会在堆内存中开辟区域存储3个整数。
- arr是变量,在栈中,arr中存储的是数组对象在堆内存中的地址值。
4.4.2 多个变量指向同一个数组的问题
- 多个变量指向同一个数组
- 使用数组时常见的一个问题
-
如果某个数组变量存储的地址是null,那么该变量将不再指向任何数组对象
-
总结 -
多个数组变量,指向同一个数组对象的原因是什么?需要注意什么?
- 原因:多个数组变量中存储的是同一个数组对象的地址
- 注意:多个变量修改的都是同一个数组对象中的数据
-
如果某个数组变量中存储的null,代表什么意思?需要注意什么?
- 代表这个数组变量没有指向数组对象
- 可以输出这个变量,但是不能用这个数组变量去访问数据或者访问数组长度,会报空指针异常:NullPointerException
4.5. Debug 工具的使用
- Debug工具
- IDEA自带的断点调试工具,可以控制代码从断点开始一行一行的执行,然后详细观看程序执行的情况。
- Debug工具基本使用步骤
-
在需要控制的代码行左侧,点击一下,形成断点
-
选择使用Debug方式启动程序,启动后程序会在断点暂停
-
控制代码一行一行的往下执行
-
-
到此教程就结束了.
-
转载: 请附上本文链接.
-
如果文章对你有帮助, 可以点赞收藏一下, 以防下次需要可以快速找到.