01-数组
-
介绍 : 数组就是一种容器, 可以存储同种数据类型的多个值
同种数据类型, 不要理解的过于死板, 要结合隐式转换去考虑
double[] arr = {11.1, 22.2, 33};
System.out.println(arr[2]); // 33.0
int[] arr = {10,20,'a'};
System.out.println(arr[2]); // 97
建议数组中尽量存储同种数据类型
-
使用场景 :
-
如果发现要操作的数据有多个, 并且多个数据属于同一组, 就可以考虑使用数组来进行维护
-
已知班级成绩为 100 90 70 60 ...
-
找出最大值
-
找出最小值
-
求和
-
-
02-数组的定义格式
-
格式1
-
数据类型[] 数组名;
int[] arr;
-
-
格式2
-
数据类型 数组名[];
int arr[];
-
-
注意 :
-
这种定义格式, 定义出来的, 只是数组类型的变量而已
-
容器还没有被真正的创建
-
03-数组的静态初始化
-
初始化 : 所谓数组初始化, 就是在内存中, 为数组容器开辟空间, 并将数据存入空间的过程
-
静态初始化格式 :
-
完整格式
数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, 元素3...};
int[] arr = new int[]{11,22,33};
-
简化格式
数据类型[] 数组名 = {元素1, 元素2, 元素3...};
int[] arr = {11,22,33};
-
-
细节 :
-
打印数组名, 会看到数组的内存地址
[I@233ac14
含义: @ : 分隔符 [ : 表示当前内存空间是数组类型, 几个空括号就是几维数组 I : 当前数组是int类型 233ac14 : 十六进制内存地址
-
04-数组的元素访问
-
目标 : 能够从数组中取出元素, 并使用
-
格式 : 数组名 [索引];
-
索引 (角标 | 下标) : 数组中空间所对应的编号, 编号从 0 开始, 逐个 + 1增长
-
数组的最大索引 : 数组名.length - 1
-
public class ArrayDemo3 {
/*
数组的元素访问 :
数组名[索引];
索引(角标, 下标) : 数组中空间所对应的编号, 编号从0开始, 逐个+1增长
*/
public static void main(String[] args) {
int[] arr = {11, 22, 33, 44, 55};
// 将数组中22元素, 取出来打印在控制台
System.out.println(arr[1]);
// 将数组中33元素, 修改为66
arr[2] = 66;
System.out.println(arr[2]);
// 判断数组中第一个元素, 是奇数还是偶数
if(arr[0] % 2 == 0){
System.out.println(arr[0] + "是一个偶数");
}else{
System.out.println(arr[0] + "是一个奇数");
}
// 根据数组中第二个元素, 决定在控制台打印多少次HelloWorld
for(int i = 1; i <= arr[1]; i++){
System.out.println("HelloWorld");
}
}
}
05-数组的遍历操作
-
介绍 : 将数组中的 [每一个] 元素, 取出来进行使用 (打印, 判断, 求和...)
public class ArrayDemo4 {
/*
数组的遍历 : 将数组中的每一个元素, 取出来进行操作
-------------------------------------------------------------------
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[4]);
弊端: 代码的复用性太差
解决: 使用循环来做优化
-------------------------------------------------------------------
for(int i = 0; i < 5; i++){
// i = 0 1 2 3 4
System.out.println(arr[i]);
}
弊端: 循环的次数, 写死了(硬编码)
解决: 使用数组中默认存在的属性 length
- 数组名.length : 动态的, 获取到数组的长度 (元素的个数)
-------------------------------------------------------------------
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
*/
public static void main(String[] args) {
int[] arr = {11, 22, 33, 44, 55};
// 数组名.fori
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
案例 : 求和
public class ArrayTest1 {
/*
需求: 已知数组元素为 {11,22,33,44,55} 将数组中偶数元素, 求和, 并打印在控制台
数组遍历的使用场景: 如果你要完成的需求, 需要操作到数组中的 [每一个] 元素, 就需要遍历数组
分析:
1. 定义数组, 存储元素 {11,22,33,44,55}
2. 准备求和变量, sum, 用于累加操作
3. 遍历数组, 获取到每一个元素
4. 判断当前元素, 是否是偶数
5. 如果是偶数, 跟sum进行累加
6. 在遍历结束后, 将sum结果打印在控制台
*/
public static void main(String[] args) {
// 1. 定义数组, 存储元素 {11,22,33,44,55}
int[] arr = {11, 22, 33, 44, 55};
// 2. 准备求和变量, sum, 用于累加操作
int sum = 0;
// 3. 遍历数组, 获取到每一个元素
for (int i = 0; i < arr.length; i++) {
// 4. 判断当前元素, 是否是偶数
// i : 在循环内部, 现在只是一个索引
// arr[i] : 元素
if(arr[i] % 2 == 0){
// 5. 如果是偶数, 跟sum进行累加
sum += arr[i];
}
}
// 6. 在遍历结束后, 将sum结果打印在控制台
System.out.println("偶数和为:" + sum);
}
}
案例 : 求最大值
public class ArrayTest2 {
/*
需求: 已知数组元素为 {22, 11, 55, 44, 33} 找出最大值并打印在控制台
*/
public static void main(String[] args) {
int[] arr = {-22, -11, -55, -44, -33};
// 1. 假设数组中第一个元素, 就是最大值
int max = arr[0];
// 2. 遍历数组, 获取每一个元素
for (int i = 1; i < arr.length; i++) {
// arr[i] : 从数组中取出来的元素
// 3. 比较
if (arr[i] > max) {
// 4. 让max遍历记录更大的值
max = arr[i];
}
}
// 5. 打印最大值
System.out.println("最大值为:" + max);
}
}
案例 : 综合案例
public class ArrayTest3 {
/*
需求:
已知班级学生成绩为
int[] arr = {100,50,20,90,90};
1. 找出数组最大值, 并打印在控制台
2. 找出数组最小值, 并打印在控制台
3. 求总成绩, 并打印在控制台
4. 计算出平均值, 并打印在控制台
5. 统计出低于平均值元素的个数
*/
public static void main(String[] args) {
int[] arr = {100, 50, 20, 90, 90};
// 1. 求最大值
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if(arr[i] > max){
max = arr[i];
}
}
// 2. 求最小值
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
if(arr[i] < min){
min = arr[i];
}
}
// 3. 求和
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
// 4. 平均分
double avg = (sum * 1.0) / arr.length;
// 5. 统计低于平均分人数
int count = 0;
for (int i = 0; i < arr.length; i++) {
if(arr[i] < avg){
count++;
}
}
System.out.println("最高分为:" + max);
System.out.println("最低分为:" + min);
System.out.println("总成绩为:" + sum);
System.out.println("平均分为:" + avg);
System.out.println("低于平均分人数为:" + count);
}
}
07-数组的动态初始化
-
介绍 : 在初始化的时候, 只需要指定长度, 系统就会分配默认值
-
格式 : 数据类型[] 数组名 = new 数据类型[长度];
int[] arr = new int[3];
-
默认值的分类 :
整数 : 0 小数 : 0.0 布尔 : false 字符 : '\u0000' ---> Unicode字符 ---> 常见的体现就是空白字符 引用数据类型 : null ---------------------------------------------------- 引用数据类型 : 数组, 类, 接口
两种初始化的区别 :
动态初始化 : 手动指定长度, 系统分配默认值
静态初始化 : 手动指定元素, 由系统计算出数组的长度
两种初始化的使用场景 :
-
静态初始化 : 如果要操作的数据, 需求中已经明确告知了, 直接静态初始化
举例 : 已知元素为 10 20 30 40 50 , 找出最大值 int[] arr = { 10, 20, 30, 40, 50 };
-
动态初始化 : 只明确元素个数, 不明确具体数值
import java.util.Scanner;
public class ArrayDemo6 {
/*
两种初始化的区别 :
1. 动态初始化: 手动指定长度, 系统会分配默认值
2. 静态初始化: 手动指定元素, 系统会根据元素的个数, 计算出数组的长度
两种初始化的使用场景 :
1. 静态初始化: 如果需求中, 已经明确告知要操作的数据有哪些, 直接静态初始化
需求 : 已知班级成绩为 100 90 80 100 20, 求出最大值
int[] arr = {100,90,80,100,20};
2. 动态初始化: 只知道要存储几个元素, 不明确具体数值
需求 : 键盘录入5个学生成绩, 求出最高分
需求 : 产生10个1~100之间的随机数, 找出最小值
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] arr = new int[5];
for (int i = 0; i < arr.length; i++) {
System.out.println("请输入第" + (i + 1) + "位学生的成绩: ");
arr[i] = sc.nextInt();
}
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if(arr[i] > max){
max = arr[i];
}
}
System.out.println("最大值为:" + max);
}
}
import java.util.Random;
public class ArrayTest4 {
/*
需求 : 产生10个1~100之间的随机数, 找出最小值
*/
public static void main(String[] args) {
Random r = new Random();
// 1. 准备一个长度为10的数组, 用于存储产生的随机数
int[] arr = new int[10];
System.out.println("产生的10个随机数为: ");
// 2. 产生10个1~100之间的随机数, 并存入数组
for (int i = 0; i < arr.length; i++) {
arr[i] = r.nextInt(100) + 1;
System.out.println(arr[i]);
}
// 3. 找出最小值
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
if(arr[i] < min){
min = arr[i];
}
}
System.out.println("最小值为:" + min);
}
}
08-数组的内存图
-
目标 : int[] arr = {11,22,33}; 脑海中就要有数组的内存结构
09-数组的常见问题
-
ArrayIndexOutOfBoundsExcpetion : 数组索引越界异常
-
原因 : 访问了不存在的索引
-
-
NullPointerException : 空指针异常
-
原因 : 当引用数据类型的变量, 被赋值为null, 意味着和堆内存的指向被切断了
- 这时候还要去访问堆内存数据, 就会出现空指针异常
int[] arr = {11,22,33}; arr = null; System.out.println(arr[0]); // 这句代码就会出现空指针异常
-
10-二维数组的介绍
-
介绍 : 二维数组也是一种容器, 容器中存储的都是一维数组
-
简单理解 : 数组容器的嵌套
-
-
使用场景 :
-
发现手里要操作的一维数组有多个.
-
这多个一维数组, 还是一个整体, 就可以使用二维数组进行维护
-
第一季度:22,66,44 第二季度:77,33,88 第三季度:25,45,65 第四季度:11,66,99
11-二维数组静态初始化
-
格式
完整格式 : 数据类型[][] 数组名 = new 数据类型[][]{ {一维数组1}, {一维数组2}...};
int[][] arr = new int[][] {
{11,22,33},
{44,55,66}
};
------------------------------------------------------------------- 简化格式 : 数据类型[][] 数组名 = { {一维数组1}, {一维数组2}...};
int[][] arr = {
{11,22,33},
{44,55,66}
};
-
二维数组的元素访问
格式: 数组名[m索引][n索引] m索引 : 访问哪一个一维数组 n索引 : 访问一维数组中的哪一个元素
System.out.println(arr[0][1]); //22
12-二维数组遍历操作
-
思路 :
-
遍历二维数组, 获取到每一个一维数组
-
继续遍历一维数组, 获取内部元素
-
int[][] arr = {
{11,22,33},
{44,55,66}
};
// 遍历二维数组, 获取到每一个一维数组
for(int i = 0; i < arr.length; i++){
// arr[i] : 每一个一维数组
// 继续遍历一维数组, 获取内部元素
for(int j = 0; j < arr[i].length; j++){
System.out.println(arr[i][j]);
}
}
public class ArrayTest6 {
/*
第一季度:22,66,44
第二季度:77,33,88
第三季度:25,45,65
第四季度:11,66,99
需求: 统计出该公司, 每个季度的销售总额, 以及整个年度的销售总额
*/
public static void main(String[] args) {
int[][] arr = {
{22, 66, 44},
{77, 33, 88},
{25, 45, 65},
{11, 66, 99}
};
int total = 0;
// 1. 遍历二维数组, 获取到每一个一维数组
for (int i = 0; i < arr.length; i++) {
int sum = 0;
// 2. 继续遍历一维数组, 获取每一个元素
for (int j = 0; j < arr[i].length; j++) {
sum += arr[i][j];
}
// 当内循环执行完毕, 意味着, 一个季度已经操作完毕了
System.out.println("第" + (i + 1) + "个季度的销售额为:" + sum);
total += sum;
}
System.out.println("年度总销售额为:" + total);
}
}
13-二维数组动态初始化
-
格式 :
数据类型[][] 数组名 = new 数据类型[m][n]; m : 指定这个二维数组, 可以存储多少个一维数组 n : 指定每一个一维数组中, 可以存储多少个元素 int[][] arr = new int[3][5]; 这个二维数组, 可以存储3个一维数组, 每一个一维数组, 又可以存储5个元素