Day05目标:
-
掌握嵌套循环的使用规则;
-
了解什么是数组,数组可以解决什么问题?
-
掌握数组的定义,初始化;
-
掌握数组的访问、遍历;
-
掌握数组的复制、排序;
-
预计代码量:课上130行,作业260行
break关键字
- break用在循环中,用于跳出循环,常常与if一同使用,在某种特定条件下跳出循环;
for (int = 1; num <= 9; num++) {
if (num == 4) { // 在某种特定条件下,提前结束循环
break; // 跳出循环
}
System.out.println(num + "*9=" + num * 9);
}
continue关键字(比较鸡肋)
- continue关键字用在循环中,用于跳过循环体中剩余语句而进入下一次循环;
// 输出9的乘法表,跳过能被3整除的
for (int num = 1; num <= 9; num++) {
if (num % 3 == 0) {
continue; // 跳出循环体中剩余的语句而进入下一次循环
}
System.out.println(num + "*9=" + num * 9);
}
/*
输出:
1 * 9 = 9
2 * 9 = 18
4 * 9 = 36
5 * 9 = 45
7 * 9 = 63
8 * 9 = 72
*/
// 等价于:输出9的乘法表,只要不能被3整除
for (int num = 1; num <= 9; num++) {
if (num % 3 != 0) {
System.out.println(num + "*9=" + num * 9);
}
}
嵌套循环
- 案例:打印九九乘法表:(补充:\t:水平制表转义字符,固定占8位)
package day05;
public class MultiTable {
public static void main(String[] args) {
// int num = 9;
// for (int i = 1; i <= num; i++) {
// System.out.print(i + "*" + num + "=" + i * num + "\t"); // print line = println:换行输出 print = 本行输出
// }
// System.out.println(); // 换行
for (int num = 1; num <= 9; num++) { // 控制行
for (int i = 1; i <= num; i++) { // 控制列
System.out.print(i + "*" + num + "=" + i * num + "\t");
}
System.out.println(); // 换行
}
/*
执行过程:
num=1时: num=2时: num=3时: ......
i=1 1*1=1 i=1 1*2=2 i=1 1*3=3
i=2 false i=2 2*2=4 i=2 2*3=6
换行 i=3 false i=3 3*3=9
换行 i=4 false
换行
*/
}
}
-
循环中套循环,常常多行多列时使用,所有多行多列都可以使用嵌套循环,外层循环控制行,内层循环控制列
-
执行规则:
- 外层循环走一次,内层循环走所有次!(类似时针分针的关系)
-
建议:嵌套的层数越少越好,能用一层就不用两层,能用两层就不用三层…如果出现了只有多层嵌套才能解决的问题,一定是设计出现问题。
-
break默认只能跳出当前一层循环;实际应用场景不会出现需要跳出多层循环的情况出现,如果出现可以使用JAVA的保留字。
数组
什么是数组?数据的组合!
为什么用数组?数组的概念
-
实现:存储100名学生的成绩
double score1, score2, score3, ...... ,score100;
-
实现:找到这100名学生成绩当中的高分
int max = score1; if (score2 > max) { ... } else if (score3 > max) { ... } ...
-
相同数据类型元素(数据)的集合,数组内部的数必须是相同数据类型的元素!就像衣柜!
-
数组是一种引用数据类型,将一组类型相同、逻辑相关的数据,存储到系统中
定义数组
int a; // 声明一个整型变量,名为a
int [] b; // 声明一个整型数组变量,名为b
int a = 5;
int [] = 5; // 编译错误,数据类型不匹配
int [] b = new int [4]; // 声明是说我要弄个衣柜,new数组才能买衣柜 ,衣柜内部写几就是能装几个数
-
定义数组的语法:
-
数据类型[] 数组名 = new 数据类型[大小];
-
int[] arr = new int[5];
-
-
定义数组,当我们使用
new
以后,Java会自动给我们一个默认值:-
int[] a = new int[3];
// 声明整型数组a,包含3个元素,每个元素都是int类型,默认值为0 -
double[] b = new double[10];
// 声明浮点型数组b,包含10个元素,每个元素都是double类型,默认值为0.0 -
boolean[] c = new boolean[26];
// 声明布尔型数组c,包含26个元素,每个元素都是boolean类型,默认值为false
-
-
数组元素默认值规则:
-
byte short int long char → 默认值:0
-
float double → 默认值:0.0
-
boolean → 默认值false
-
数组的初始化
- 给元素初始化:
// 2)数组的初始化:...初始化的是数组中的元素
int [] arr = new int [3]; // 0, 0, 0
int [] arr1 = {2, 5, 8}; // 2, 5, 8
int [] arr2 = new int [] {2, 5, 8}; // 2, 5, 8 // 注意[ ]中不能写元素个数了
int [] arr3;
// arr3 = {2, 5, 8}; // 编译错误,此方式只能声明同时初始化
arr3 = new int [] {2, 5, 8};
数组的访问
-
数组的长度即元素的个数(柜子有几个门?)
-
通过
数组名.length
可以获取数组的长度
int [] arr = new int [3];
System.out.println("数组的长度为" + arr.length); // 返回:数组的长度为3
通过下标访问数组的元素
int [] arr = new int [3]; // 0, 0, 0
// 想给第二个元素赋值为100
- 我们可以通过下标/索引来访问元素,下标从0开始,最大到**(数组长度-1)**
int [] arr = new int [3]; // 0, 0, 0
arr[0] // 代表整型数组arr中的第1个元素 (int型)
arr[1] // 代表整型数组arr中的第2个元素 (int型)
arr[2] // 代表整型数组arr中的第3个元素 (int型)
// 3)数组的访问:
int [] arr4 = new int [3];
System.out.println("数组的长度:" + arr4.length); // 3)长度即元素个数
System.out.println("数组第1个元素为:" + arr4[0]); // 0
arr4[0] = 100; // 给第一个元素赋值为100
arr4[1] = 100; // 给第二个元素赋值为200
arr4[2] = 300; // 给第三个元素赋值为300
// arr4[3] = 400; // 运行时发生数组越界异常!
System.out.println(arr4[2]); // 300 输出最后一个元素的值
System.out.println(arr4[arr4.length - 1]); // 300 输出最后一个元素的值
数组的遍历
- 遍历/迭代:从头到尾挨个走一遍
// 需求,给每个元素都赋值为100
int [] arr = new int [10];
arr[0] = 100;
arr[1] = 100;
arr[2] = 100;
arr[3] = 100;
arr[4] = 100;
arr[5] = 100;
arr[6] = 100;
arr[7] = 100;
arr[8] = 100;
arr[9] = 100;
// 需求,给每个元素都赋值为100
// 改进方案:因为出现了持续做同一件事,可以用for循环
int [] arr = new int [10];
for (int i = 0; i < arr.length; i++) {
arr [i] = 100
System.out.println(arr[i]); // 输出每个元素的值
}
- 案例:寻找最大值:
package day05;
public class MaxOfArray {
public static void main(String[] args) {
int [] arr = new int[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 100);
System.out.println(arr[i]);
}
System.out.println("————————————————————————————————————————");
// 找最大值:
int maxNum = arr[0]; // 假设第1个元素为最大值
for (int j = 1; j < arr.length; j++) { // 遍历剩余元素
if (arr[j] > maxNum) { // 若剩余元素大于max
maxNum = arr[j]; // 将max修改为较大的
}
}
System.out.println("最大值为:" + maxNum);
}
}
数组的复制
-
使用
System.arraycopy()
方法可以实现对数组的复制,一共有5个参数可供选择,注意不要产生数组越界!-
参数1:从哪个数组中Copy?
-
参数2:从下标为几的位置开始Copy?
-
参数3:Copy到哪个数组?
-
参数4:在下标为几的位置开始粘贴?
-
参数5:复制源数组中多少个值?
-
package day05;
public class ArrayCopyDemo {
public static void main(String[] args) {
int [] a = {10, 20, 30, 40, 50};
int [] b = new int [6]; // 0, 0, 0, 0, 0, 0
System.arraycopy(a, 1, b, 0, 4);
// a:源数组
// 1:源数组的起始下标
// b:目标数组
// 0:目标数组的起始下标
// 4:要复制的元素的个数
for (int i = 0; i < b.length; i++) {
System.out.println("数组的内容:" + b[i]);
}
}
}
Arrays.copyOf()方法对数组的复制
-
使用
Arrays.copyOf()
可以实现对数组的复制,有两个参数可以设置-
参数1:源数组,被复制的数组
-
参数2:目标数组的长度,要复制该数组的多少数据?
-
int [] a = {10, 20, 30, 40, 50};
// a:源数组
// b:目标数组
// c:目标数组的长度
// -- 若目标数组的长度 > 源数组的长度 -- 末尾补默认值
// -- 若目标数组的长度 < 源数组的长度 -- 则将末尾多出的部分截掉
int [] b = Array.copyOf(a, 6);
for (int i = 0; i < b.length; i++) {
System.out.println("新的b数组:" + b[i]);
}
int [] c = Array.copyOf(a, 4);
for (int i = 0; i < c.length; i++) {
System.out.println("新的c数组:" + c[i]);
}
数组的扩容
- 数组的长度在创建数组后是不可以改变的!数组元素的内存空间是连续的!
int [] a = {10, 20, 30, 40, 50};
a = Array.copyOf(a, a.length + 1); // a 的新数组长度增加到6,并补齐下标5的位置为默认值0
-
不是说不能改变长度吗?数组元素的内存空间不是连续的吗?
- 所谓的扩容其实是指创建一个更大的新数组,并将源数组的内容复制进去,也就说明原来的数组永远无法访问了,Java的自动垃圾回收机制会把源数组清理。
int [] a = {10, 20, 30, 40, 50};
a = ArraycopyOf(a, a.length + 1);
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
- 同理,缩容一样的操作流程,一样的底层原理!
int [] a = {10, 20, 30, 40, 50};
a = ArraycopyOf(a, a.length - 1);
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
回到MaxOfArray.java
中
数组的排序
-
排序是对数组施加的最常用的算法;
-
所谓排序,指将数组元素按照**从大到小(降序)或从小到大(升序)**的顺序重新排列;
-
常见的排序算法有:冒泡排序、插入排序、快速排序、选择排序、希尔排序等。
使用Arrays.sort()对数组排序
- Java提供的
Arrays.sort()
封装了数组的排序算法:
package day05;
import java.util.Arrays;
import java.util.Random;
public class ArraySortDemo {
public static void main(String[] args) {
int [] arr = new int[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random() * 100);
System.out.println(arr[i]);
}
Arrays.sort(arr); // 对数组arr就行升序排列
System.out.print("排序后:");
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
System.out.println("倒着输出:");
for (int i = arr.length - 1; i >= 0; i--) { // 数据还是升序的,只是倒着打印
System.out.println(arr[i]);
}
System.out.println("第一个元素为:" + arr[0]); // 最小的那个数
// 补充说明,换种方式创建随机数
Random random = new Random();
int num = random.nextInt(100); // 生成0到99的随机数
System.out.println(num);
// 这种方法的好处在于更易于使用,而且不知可以生成随机整数,还可以用.nextDouble()生成随机小数......
// 等价于:
num = (int) (Math.random() * 100);
System.out.println(num);
}
}