一、认识数组
数组就是一个容器,用来存储一批同种类型的数据
数组:可以看成是相同类型元素的一个集合,数组属于引用数据类型,存储的数组在内存中的地址信息
如现实中车库:
注意:
1. 数组中存放的元素其类型相同
2. 数组的空间是连在一起的
3. 每个空间有自己的编号,其实位置的编号为0,即数组的下标
二、数组的定义和访问
2.1 静态初始化数组
静态初始化:定义数组的时候就直接给数组赋值
格式:
// 完整格式 数据类型[] 数组名 = new 数据类型[] {元素1, 元素2, 元素3...}; int[] ages = new int[] {12, 24, 36}; double[] scores = new double[] {89.9, 99.5, 59.5, 88.0};
// 简化格式 数据类型[] 数组名 = {元素1, 元素2, 元素3...}; int[] ages = {12, 24, 36};
//这种格式也可以,但不常见 数据类型 数组名[] = {元素1, 元素2, 元素3...}; int ages[] = {12, 24, 36};
使用场景:一旦确定了数组的具体值,我们就使用这种方式存储批量数据
案例:
需求:某部门5名员工的销售额分别是:16、26、36、6、100,请计算出他们部门的销售额
public class Test {
public static void main(String[] args) {
int[] money = {16, 26, 36, 6, 100};
int sum = 0;
for (int i = 0; i < money.length; i++) {
sum += money[i];
}
System.out.println(sum); //输出 184
}
}
2.2 动态初始化数组
定义数组时先不存入具体的元素值,只确定数组存储的数据类型和数组的长度
格式:
数据类型[] 数组名 = new 数据类型[长度];
int[] arr = new int[3];
//后赋值
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
注意:
1. 静态初始化和动态初始化数组的写法是独立的,不可以混用
int[] arr = new int[3]{30, 40, 50}; //err
2. 动态初始化数组元素默认值规则:即数组中的元素还没有被赋值时的值
使用场景:适合一开始不能确定具体数据的情况,先定义数组,后赋值数据进去
案例:
需求:歌唱比赛,需要录入6名评委的评分,录入完毕后立即输出平均分做为选手得分
import java.util.Scanner; public class Test { public static void main(String[] args) { double[] scores = new double[6]; Scanner sc = new Scanner(System.in); double sum = 0; for (int i = 0; i < scores.length; i++) { System.out.println("请输入第" + (i + 1) + "个评委的评分"); scores[i] = sc.nextInt(); sum += scores[i]; } System.out.println("选手的最终得分是:" + (sum / scores.length)); } }
2.3 数组在计算机中的基本原理
注意:数组变量中存储的是数组在内存中的地址,数组是一种引用数据类型
2.4 数组的访问
格式:
数组名[索引]//取值 System.out.println(arr[0]); // 12 //赋值 arr[2] = 100; System.out.println(arr[2]); // 100
数组的长度属性:length
// 获取数组的长度(也就是数组元素的个数) System.out.println(arr.length); // 3数组的最大索引是:数组名.length - 1 // 前提是元素个数大于 0
注意事项:
a. 什么类型的数组就只能存放什么类型的数据
b. 数据类型[ ] 变量名称 可以写成 数据类型 变量名称[ ]
c. 数组一旦定义出来,程序执行的过程中,长度、类型就固定了
d. 访问数组时,使用的索引超过了数组最大索引,
执行程序时会出bug,出现一个索引越界的异常显示
2.5 数组的遍历
什么是数组的遍历?
数组的遍历就是一个一个数据的访问
为什么要遍历数组?
当你使用数组时,可能需要完成以下功能:
- 数据处理:你可能需要读取数组中的每个元素,对其进行某种计算或转换,然后将结果存储回数组或另一个数据结构中。
- 搜索:你可能正在寻找数组中的特定元素或满足某些条件的元素。遍历数组是检查每个元素是否满足条件的最直接方法。
- 排序:排序算法(如冒泡排序、插入排序、选择排序、快速排序等)都需要遍历数组多次,以比较和重新排列元素。
- 统计和聚合:你可能需要计算数组中的元素总数、唯一元素的数量、最大值、最小值、总和或平均值等。遍历数组是收集这些统计信息的必要步骤。
- 验证:你可能需要验证数组是否满足某些条件,例如是否所有元素都是正数、是否没有重复的元素等。遍历数组是检查这些条件的有效方法。
- 可视化或输出:你可能需要将数组的内容以某种方式显示给用户或写入文件。遍历数组是逐个访问和输出元素的标准方法。
- 构建新的数据结构:你可能需要基于数组的内容构建新的数据结构,如哈希表、图或树。遍历数组是获取所需信息以构建这些新结构的关键步骤。
- 与其他数据结构交互:在处理更复杂的数据时,你可能需要将数组与其他数据结构(如链表、队列、栈等)结合使用。遍历数组可能是将数据从一个结构移动到另一个结构的一部分。
这些功能都需要遍历数组
如何遍历数组呢?
//方法一: 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 x : ages) { System.out.println(x); }
2.6 数组的内存图和数组案例
运行一个Java程序,主要看JVM中包含的 方法区 栈内存 堆内存 的内存分布
数组在计算机中的执行原理
1. 首先,当程序执行时,会把 .class 文件提取到方法区里,.class 文件中有一个 main 方法
2. 接着,把 main 方法加载到栈内存中执行,然后会正式执行 main方法的第一行代码,第一行代 码在定义一个基本类型的变量,这个基本类型的变量会在栈内存中开辟空间,即在 main 方法中 开辟空间,空间内储存的就是数据 10
3. 接着,执行第二行代码,这行代码是输出变量 a ,会把变量 a 中存储的数据 10 直接打印
4. main 方法继续执行到第三行代码,先在 main 方法中开辟 arr 变量的空间,接着执行等号右边 的代码,这个代码是在 new 一个数组对象,new 出来的这个对象会放在堆内存,所以它会在 堆内存中开辟一块空间,这块空间会分成三块等分的区域,第一区域存 11,第二区域存 22,第 三个区域存 33,每个元素都有自己的索引,并且也会有一个地址,这个地址会被赋值给 arr 这 个变量,由arr 指向堆内存中的这个数组对象,这就是引用类型变量的执行原理
5. main 方法继续执行到第四行代码,输出引用类型变量 arr ,将 arr 中存储的地址打印出来
6. main 方法继续执行到第五行代码,通过索引把 arr 数组中第二个位置的值 22 打印出来
7. main 方法继续执行到第六、七、八行代码,通过 arr 里的地址找到堆内存中的数组对象,再找 到第一个位置改成 44,把第二个位置改为 55,把第三个位置给为 66
8. main 方法继续执行到第九、十、十一行代码,根据数组变量里的地址,找到堆内存中的数组对 象,再通过索引找到对应位置的值并打印
案例:某公司开发部 5 名开发人员,要进行项目进展汇报演讲,现在采取随机排名后进行汇报
先依次录入 5 名员工工号,然后展示出一组随机的排名顺序,如:
import java.util.Arrays; import java.util.Random; import java.util.Scanner; public class Immediatelyranked { public static void main(String[] args) { int[] arr = new int[5]; Scanner sc = new Scanner(System.in); for (int i = 0; i < arr.length; i++) { System.out.println("请输入第" + (i + 1) + "名员工的工号"); arr[i] = sc.nextInt(); } Random r = new Random(); for (int i = 0; i < arr.length; i++) { int p = r.nextInt(arr.length); int temp = arr[i]; arr[i] = arr[p]; arr[p] = temp; } System.out.println(Arrays.toString(arr)); } }
数组使用的常见问题
1. 不要访问超过数组最大索引,否则出现数组访问异常
2. 空指针异常,