# 第 03 章:随堂复习与企业真题(流程控制语句)


# 一、随堂复习

# 1.1 (了解)流程控制结构

  • 顺序结构
  • 分支结构
    • if-else
    • switch-case
  • 循环结构
    • for
    • while
    • do-while

# 1.2 分支结构之 1:if-else

  • 在程序中,凡是遇到了需要使用分支结构的地方,都可以考虑使用 if-else。
  • if-else 嵌套的练习多关注

# 基本语法

/*
分支结构1:if-else条件判断结构

1. 格式
格式1:
if(条件表达式){
  	语句块;
}

格式2:"二选一"
if(条件表达式) { 
  	语句块1;
}else{
  	语句块2;
}

格式3:"多选一"
if (条件表达式1) {
  	语句块1;
} else if (条件表达式2) {
  	语句块2;
}
...
}else if (条件表达式n) {
 	语句块n;
} else {
  	语句块n+1;
}


*/
class IfElseTest {
	public static void main(String[] args) {
		
		/*
		案例1:成年人心率的正常范围是每分钟60-100次。体检时,
		如果心率不在此范围内,则提示需要做进一步的检查。
		*/
		int heartBeats = 89;
		//错误的写法:if(60 <= heartBeats <= 100){

		if(heartBeats < 60 || heartBeats > 100){
			System.out.println("你需要做进一步的检查");
		}

		System.out.println("体检结束");

		//**********************************
		/*
		案例2:定义一个整数,判定是偶数还是奇数    
		*/
		int num = 13;
		if(num % 2 == 0){
			System.out.println(num + "是偶数");
		}else{
			System.out.println(num + "是奇数");
		}
	}
}

# 案例

/*
岳小鹏参加 Java 考试,他和父亲岳不群达成承诺:
如果:
成绩为 100 分时,奖励一辆跑车;
成绩为 (80,99] 时,奖励一辆山地自行车;
当成绩为 [60,80] 时,奖励环球影城一日游;
其它时,胖揍一顿。
说明:默认成绩是在 [0,100] 范围内
结论:
1. 如果多个条件表达式之间没有交集(理解是互斥关系),则哪个条件表达式声明在上面,哪个声明在下面都可以。
   如果多个条件表达式之间是包含关系,则需要将范围小的条件表达式声明在范围大的条件表达式的上面。否则,范围小的条件表达式不可能被执行。
*/
class IfElseTest1 {
	public static void main(String[] args) {
		
		int score = 61;
		// 方式 1:
		/*
		if (score == 100){
			System.out.println ("奖励一辆跑车");
		} else if (score > 80 && score <= 99){
			System.out.println ("奖励一辆山地自行车");
		} else if (score >= 60 && score <= 80){
			System.out.println ("奖励环球影城一日游");
		} else {
			System.out.println ("胖揍一顿");
		}
		*/
		
		// 方式 2:
		score = 88;
		if(score == 100){
			System.out.println("奖励一辆跑车");
		}else if(score > 80){
			System.out.println("奖励一辆山地自行车");
		}else if(score >= 60){
			System.out.println("奖励环球影城一日游");
		}else{
			System.out.println("胖揍一顿");
		}
		// 特别的:
		if(score == 100){
			System.out.println("奖励一辆跑车");
		}else if(score > 80){
			System.out.println("奖励一辆山地自行车");
		}else if(score >= 60){
			System.out.println("奖励环球影城一日游");
		}
		/*else {
			System.out.println ("胖揍一顿");
		}
		*/
		
	}
}
/*
测试 if-else 的嵌套使用
案例:
由键盘输入三个整数分别存入变量 num1、num2、num3,对它们进行排序 (使用 if-else if-else),并且从小到大输出。
拓展:你能实现从大到小顺序的排列吗?
1. 从开发经验上讲,没有写过超过三层的嵌套 if-else 结构。
2. 如果 if-else 中的执行语句块中只有一行执行语句,则此执行语句所在的一对 {} 可以省略。但是,不建议省略
*/
class IfElseTest2 {
	public static void main(String[] args) {
		
		int num1 = 30;
		int num2 = 21;
		int num3 = 44;
		//int num1 = 30,num2 = 21,num3 = 44;
		if(num1 >= num2){
			if(num3 >= num1)
				System.out.println(num2 + "," + num1 + "," + num3);
			else if(num3 <= num2)
				System.out.println(num3 + "," + num2 + "," + num1);
			else
				System.out.println(num2 + "," + num3 + "," + num1);	
				//System.out.println(num2 + "," + num3 + "," + num1);	
				
		}else{ // num1 < num2
			if(num3 >= num2){
				System.out.println(num1 + "," + num2 + "," + num3);
			}else if(num3 <= num1){
				System.out.println(num3 + "," + num1 + "," + num2);
			}else{
				System.out.println(num1 + "," + num3 + "," + num2);
			}
		}
	}
}

# 1.3 分支结构之 2:switch-case

  • 在特殊的场景下,分支结构可以考虑使用 switch-case

    • 指定的数据类型:byte \ short \ char \ int ; 枚举类(jdk5.0)\ String (jdk7.0)
    • 可以考虑的常量值有限且取值情况不多。
  • 特别之处:case 穿透

  • 在能使用 switch-case 的情况下,推荐使用 switch-case,因为比 if-else 效率稍高

# 基本语法

/*
分支结构之 switch-case 的使用
1. 语法格式
switch (表达式){
	
	case 常量 1:
		// 执行语句 1
		//break;
	case 常量 2:
		// 执行语句 2
		//break;
	...
	default:
		// 执行语句 2
		//break;
}
2. 执行过程:
根据表达式中的值,依次匹配 case 语句。一旦与某一个 case 中的常量相等,那么就执行此 case 中的执行语句。
执行完此执行语句之后,
		情况 1:遇到 break,则执行 break 后,跳出当前的 switch-case 结构
		情况 2:没有遇到 break,则继续执行其后的 case 中的执行语句。 ---> case 穿透
				...
			   直到遇到 break 或者执行完所有的 case 及 default 中的语句,退出当前的 switch-case 结构
3. 说明:
① switch 中的表达式只能是特定的数据类型。如下:byte \ short \ char \ int \ 枚举 (JDK5.0 新增) \ String (JDK7.0 新增)
② case 后都是跟的常量,使用表达式与这些常量做相等的判断,不能进行范围的判断。
③ 开发中,使用 switch-case 时,通常 case 匹配的情况都有限。
④ break: 可以使用在 switch-case 中。一旦执行此 break 关键字,就跳出当前的 switch-case 结构
⑤ default:类似于 if-else 中的 else 结构。
           default 是可选的,而且位置是灵活的。
4. switch-case 与 if-else 之间的转换
① 开发中凡是可以使用 switch-case 结构的场景,都可以改写为 if-else。反之,不成立
② 开发中,如果一个具体问题既可以使用 switch-case,又可以使用 if-else 的时候,推荐使用 switch-case。
  为什么?switch-case 相较于 if-else 效率稍高。
*/
class SwitchCaseTest{
	public static void main(String[] args){
		
		int num = 1;
		switch(num){
			
			case 0:
				System.out.println("zero");
				break; 
			case 1:
				System.out.println("one");
				break; // 结束当前的 switch-case 结构
			case 2:
				System.out.println("two");
				break; 
			case 3:
				System.out.println("three");
				break; 
			default:
				System.out.println("other");
				//break; 
		}
		// 另例:
		String season = "summer";
        switch (season) {
            case "spring":
                System.out.println("春暖花开");
                break;
            case "summer":
                System.out.println("夏日炎炎");
                break;
            case "autumn":
                System.out.println("秋高气爽");
                break;
            case "winter":
                System.out.println("冬雪皑皑");
                break;
            /*default:
                System.out.println ("季节输入有误");
                break;
			*/
        }
		// 错误的例子:编译不通过
		/*
		int number = 20;
		switch (number){
			case number > 0:
				System.out.println ("正数");
                break;
			case number < 0:
				System.out.println ("负数");
                break;
			default:
				System.out.println ("零");
                break;
		}
		*/
	}
}

# 案例

/*
案例 3:使用 switch-case 实现:对学生成绩大于 60 分的,输出 “合格”。低于 60 分的,输出 “不合格”。
*/
class SwitchCaseTest1 {
	public static void main(String[] args) {
		// 定义一个学生成绩的变量
		int score = 78;
		// 根据需求,进行分支
		// 方式 1:
		/*
		switch (score){
			case 0:
				System.out.println ("不及格");
				break;
			case 1:
				System.out.println ("不及格");
				break;
			//...
			
			case 100:
				System.out.println ("及格");
				break;
			default:
				System.out.println ("成绩输入有误");
				break;
		
		}
		*/
		// 方式 2:体会 case 穿透
		switch(score / 10){
			case 0:
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
				System.out.println("不及格");
				break;
			case 6:
			case 7:
			case 8:
			case 9:
			case 10:
				System.out.println("及格");
				break;
			default:
				System.out.println("成绩输入有误");
				break;
		}
		// 方式 3:
		switch(score / 60){
			case 0:
				System.out.println("不及格");
				break;
			case 1:
				System.out.println("及格");
				break;
			default:
				System.out.println("成绩输入有误");
				break;
		}
	}
}
/*
案例:编写程序:从键盘上输入 2023 年的 “month” 和 “day”,要求通过程序输出输入的日期为 2023 年的第几天。
*/
import java.util.Scanner;
class SwitchCaseTest2 {
	public static void main(String[] args) {
		//1. 使用 Scanner,从键盘获取 2023 年的 month、day
		Scanner input = new Scanner(System.in);
		System.out.println("请输入2023年的月份:");
		int month = input.nextInt();// 阻塞式方法
		System.out.println("请输入2023年的天:");
		int day = input.nextInt();
		// 假设用户输入的数据是合法的。后期我们在开发中,使用正则表达式进行校验。
		//2. 使用 switch-case 实现分支结构
		int sumDays = 0;// 记录总天数
		// 方式 1:不推荐。存在数据的冗余
		/*
		switch(month){
			case 1:
				sumDays = day;
				break;
			case 2:
				sumDays = 31 + day;
				break;
			case 3:
				sumDays = 31 + 28 + day;
				break;
			case 4:
				sumDays = 31 + 28 + 31 + day;
				break;
			//...
			case 12:
				sumDays = 31 + 28 + ... + 30 + day;
				break;
		
		}
		*/
		// 方式 2:
		switch(month){
			case 12:
				sumDays += 30;
			case 11:
				sumDays += 31;
			case 10:
				sumDays += 30;
			case 9:
				sumDays += 31;
			case 8:
				sumDays += 31;
			case 7:
				sumDays += 30;
			case 6:
				sumDays += 31;
			case 5:
				sumDays += 30;
			case 4:
				sumDays += 31;
			case 3:
				sumDays += 28; //28:2 月份的总天数
			case 2:
				sumDays += 31; //31:1 月份的总天数
			case 1:
				sumDays += day;
				//break;
		}
		
		System.out.println("2023年" + month + "月" + day + "日是当前的第" + sumDays + "天");
		
		
		input.close();// 为了防止内存泄漏
	}
}

# 1.4 循环结构之 1:for

  • 凡是循环结构,都有 4 个要素:①初始化条件 ②循环条件(是 boolean 类型) ③ 循环体 ④ 迭代条件
  • 应用场景:有明确的遍历的次数。 for(int i = 1;i <= 100;i++)

# 基本语法

/*
循环结构之一:for 循环
1. Java 中规范了 3 种循环结构:for、while、do-while
2. 凡是循环结构,就一定会有 4 个要素:
① 初始化条件
② 循环条件 ---> 一定是 boolean 类型的变量或表达式
③ 循环体
④ 迭代部分
3. for 循环的格式
for (①;②;④){
}
执行过程:① - ② - ③ - ④ - ② - ③ - ④ - ... - ②
*/
class ForTest {
	public static void main(String[] args) {
		// 需求 1:题目:输出 5 行 HelloWorld
		/*
		System.out.println("HelloWorld");
		System.out.println("HelloWorld");
		System.out.println("HelloWorld");
		System.out.println("HelloWorld");
		System.out.println("HelloWorld");
		*/
		for(int i = 1;i <= 50;i++){
			System.out.println("HelloWorld");
		}
		
		// 此时编译不通过。因为 i 已经出了其作用域范围。
		//System.out.println(i);
		// 需求 2:
		int num = 1;
        for(System.out.print("a");num < 3;System.out.print("c"),num++){
            System.out.print("b");
        }
		// 输出结果:abcbc
		System.out.println();// 换行
		// 需求 3:遍历 1-100 以内的偶数,并获取偶数的个数,获取所有的偶数的和
		int count = 0;// 记录偶数的个数
		int sum = 0;// 记录所有偶数的和
		for(int i = 1;i <= 100;i++){
			if(i % 2 == 0){
				System.out.println(i);
				count++;
				sum += i; //sum = sum + i;
			}	
		}
		System.out.println("偶数的个数为:" + count);
		System.out.println("偶数的总和为:" + sum);
		
	}
}

# 案例

/*
题目:输出所有的水仙花数,所谓水仙花数是指一个 3 位数,其各个位上数字立方和等于其本身。
例如: 153 = 1*1*1 + 3*3*3 + 5*5*5
*/
class ForTest1 {
	public static void main(String[] args) {
		
		// 遍历所有的 3 位数
		for(int i = 100;i <= 999;i++){
			
			// 针对于每一个三位数 i,获取其各个位上数值
			int ge = i % 10;
			int shi = i / 10 % 10;  // 或 int shi = i % 100 / 10
			int bai = i / 100;
			// 判断是否满足水仙花数的规则
			if(i == ge * ge * ge + shi * shi * shi + bai * bai * bai){
				System.out.println(i);
			}
		}
	}
}
/*
案例:输入两个正整数 m 和 n,求其最大公约数和最小公倍数。
比如:12 和 20 的最大公约数是 4,最小公倍数是 60。
约数:12 为例,约数有 1,2,3,4,6,12
      20 为例,约数有 1,2,4,5,10,20
倍数:12 为例,倍数有 12,24,36,48,60,72,....
      20 为例,倍数有 20,40,60,80,....
说明:
1. 我们可以在循环结构中使用 break。一旦执行 break,就跳出(或结束)当前循环结构。
2. 如何结束一个循环结构?
	方式 1:循环条件不满足。(即循环条件执行完以后是 false)
	方式 2:在循环体中执行了 break
*/
class ForTest2 {
	public static void main(String[] args) {
		int m = 12;
		int n = 20;
		// 获取 m 和 n 中的较小值
		int min = (m < n)? m : n;
		// 需求 1:最大公约数
		// 方式 1:
		int result = 1;
		for(int i = 1;i <= min;i++){
			if(m % i == 0 && n % i == 0){
				//System.out.println(i);
				result = i;
			}
		}
		System.out.println(result);
		// 方式 2:推荐
		for(int i = min;i >= 1;i--){
			if(m % i == 0 && n % i == 0){
				System.out.println("最大公约数为:" + i);
				break;// 一旦执行,就跳出当前循环结构。
			}
		}
		// 需求 2:最小公倍数
		int max = (m > n)? m : n;
		for(int i = max;i <= m * n;i++){
			if(i % m == 0 && i % n == 0){
				System.out.println("最小公倍数为:" + i);
				break;
			}
		}
	}
}

# 1.5 循环结构之 2:while

  • 应用场景:没有明确的遍历次数

# 基本语法

/*
循环结构之一:while 循环
1. 凡是循环结构,就一定会有 4 个要素:
① 初始化条件
② 循环条件 ---> 一定是 boolean 类型的变量或表达式
③ 循环体
④ 迭代部分
2.while 的格式
while (②){
}
3. 执行过程:① - ② - ③ - ④ - ② - ③ - ④ - ... - ②
4. for 循环与 while 循环可以相互转换!
5. for 循环和 while 循环的小区别:初始化条件的作用域范围不同。while 循环中的初始化条件在 while 循环结束后,依然有效。
*/
class WhileTest {
	public static void main(String[] args) {
		
		// 需求 1:遍历 50 次 HelloWorld
		int i = 1;
		while(i <= 50){
			System.out.println("HelloWorld");
			i++;// 一定要小心!不要丢了
		}
		// 需求 2:遍历 1-100 以内的偶数,并获取偶数的个数,获取所有的偶数的和
		int j = 1;
		int count = 0;// 记录偶数的个数
		int sum = 0;// 记录偶数的总和
		while(j <= 100){
			if(j % 2 == 0){
				System.out.println(j);
				count++;
				sum += j;
			}
			j++;
		}
		System.out.println("偶数的个数为:" + count);
		System.out.println("偶数的总和为:" + sum);
	}
}

# 案例

/*
随机生成一个 100 以内的数,猜这个随机数是多少?
从键盘输入数,如果大了,提示大了;如果小了,提示小了;如果对了,就不再猜了,并统计一共猜了多少次。
提示:生成一个 [a,b] 范围的随机数的方式:(int)(Math.random () * (b - a + 1) + a)
*/
import java.util.Scanner;
class WhileTest1 {
	public static void main(String[] args) {
		//1. 生成一个 [1,100] 范围的随机整数
		int random = (int)(Math.random() * 100) + 1;
		//2. 使用 Scanner,从键盘获取数据
		Scanner scan = new Scanner(System.in);
		System.out.print("请输入1-100范围的一个整数:");
		int guess = scan.nextInt();
		//3. 声明一个变量,记录猜的次数
		int guessCount = 1;
		//4. 使用循环结构,进行多次循环的对比和获取数据
		while(random != guess){
			if(guess > random){
				System.out.println("你输入的数据大了");
			}else if(guess < random){
				System.out.println("你输入的数据小了");
			}//else{
			//	break;
			//}
			
			System.out.print("请输入1-100范围的一个整数:");
			guess = scan.nextInt();
			guessCount++;
		}
		// 能结束结束,就意味着 random 和 guess 相等了
		System.out.println("恭喜你!猜对了!");
		System.out.println("共猜了" + guessCount + "次");
		
		
		scan.close();
	}
}
/*
世界最高山峰是珠穆朗玛峰,它的高度是 8848.86 米,假如我有一张足够大的纸,它的厚度是 0.1 毫米。
请问,我折叠多少次,可以折成珠穆朗玛峰的高度?
*/
class WhileTest2 {
	public static void main(String[] args) {
		
		//1. 声明珠峰的高度、纸的默认厚度
		double paper = 0.1;// 单位:毫米
		double zf = 8848860;// 单位:毫米
		
		//2. 定义一个变量,记录折纸的次数
		int count = 0;
		//3. 通过循环结构,不断调整纸的厚度 (当纸的厚度超过珠峰高度时,停止循环)
		while(paper <= zf){
			
			paper *= 2;
			count++;
		}
		
		System.out.println("paper的高度为:" + (paper / 1000) + ",超过了珠峰的高度" + (zf/1000));
		System.out.println("共折纸" + count + "次");
	}
}

# 1.6 循环结构之 3:do-while

  • 至少会执行一次循环体
  • 开发中,使用的较少

# 基本语法

/*
循环结构之一:do-while 循环
1. 凡是循环结构,就一定会有 4 个要素:
① 初始化条件
② 循环条件 ---> 一定是 boolean 类型的变量或表达式
③ 循环体
④ 迭代部分
2. do-while 的格式
do {
} while (②);
执行过程:① - ③ - ④ - ② - ③ - ④ - .... - ②
3. 说明:
1) do-while 循环至少执行一次循环体。
2) for、while、do-while 循环三者之间是可以相互转换的。
3) do-while 循环结构,在开发中,相较于 for、while 循环来讲,使用的较少。
*/
class DoWhileTest {
	public static void main(String[] args) {
		
		// 需求:遍历 100 以内的偶数,并输出偶数的个数和总和
		int i = 1;
		int count = 0;// 记录偶数的个数
		int sum = 0;// 记录偶数的总和
		do{
			if(i % 2 == 0){
				System.out.println(i);
				count++;
				sum += i;
			}
			i++;
		}while(i <= 100);
		
		System.out.println("偶数的个数为:" + count);
		System.out.println("偶数的总和为:" + sum);
		//***************************
		int num1 = 10;
		while(num1 > 10){
			System.out.println("while:hello");
			num1--;
		}
		int num2 = 10;
		do{
			System.out.println("do-while:hello");
			num2--;
		}while(num2 > 10);
	}
}

# 案例

/*
题目:模拟 ATM 取款
声明变量 balance 并初始化为 0,用以表示银行账户的余额,下面通过 ATM 机程序实现存款,取款等功能。
=========ATM========
   1、存款
   2、取款
   3、显示余额
   4、退出
请选择 (1-4):
*/
import java.util.Scanner;
class DoWhileTest1 {
	public static void main(String[] args) {
		
		//1. 定义 balance 的变量,记录账户余额
		double balance = 0.0;
		boolean flag = true; // 控制循环的结束
		Scanner scan = new Scanner(System.in);// 实例化 Scanner
		do{
			//2. 声明 ATM 取款的界面
			System.out.println("=========ATM========");
			System.out.println("   1、存款");
			System.out.println("   2、取款");
			System.out.println("   3、显示余额");
			System.out.println("   4、退出");
			System.out.print("请选择(1-4):");
			//3. 使用 Scanner 获取用户的选择
			
			int selection = scan.nextInt();
			switch(selection){
				//4. 根据用户的选择,决定执行存款、取款、显示余额、退出的操作
				case 1:
					System.out.print("请输入存款的金额:");
					double money1 = scan.nextDouble();
					if(money1 > 0){
						balance += money1;
					}
					break;
				case 2:
					System.out.print("请输入取款的金额:");
					double money2 = scan.nextDouble();
					
					if(money2 > 0 && money2 <= balance){
						balance -= money2;
					}else{
						System.out.println("输入的数据有误或余额不足");
					}
					break;
				case 3:
					System.out.println("账户余额为:" + balance);
					break;
				case 4 :
					flag = false;
					System.out.println("感谢使用,欢迎下次光临^_^");
					break;
				default:
					System.out.println("输入有误,请重新输入");
					//break;
			
			}
		
		
		}while(flag);
		
		// 关闭资源
		scan.close();
		
	}
}

# 1.7 “无限” 循环

# 基本语法

/*
"无限" 循环结构的使用
1. 格式: while (true)  或  for (;;)
2. 开发中,有时并不确定需要循环多少次,需要根据循环体内部某些条件,来控制循环的结束(使用 break)。
3. 如果此循环结构不能终止,则构成了死循环!开发中要避免出现死循环。
*/
class ForWhileTest {
	public static void main(String[] args) {
		/*
		for(;;){//while(true){
			System.out.println("I love you!");
		}
		*/
		
		// 死循环的后面不能有执行语句。
		//System.out.println("end");
		
	}
}

# 案例

/*
案例:从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,输入为 0 时结束程序。
*/
import java.util.Scanner;
class ForWhileTest1 {
	public static void main(String[] args) {
		
		Scanner scan = new Scanner(System.in);
		int positiveCount = 0;// 记录正数的个数
		int negativeCount = 0;// 记录负数的个数
		
		for(;;){//while(true){
			System.out.print("请输入一个整数(输入为0时结束程序):");
			int num = scan.nextInt(); // 获取用户输入的整数
			if(num > 0){ // 正数
				positiveCount++;
			}else if(num < 0){ // 负数
				negativeCount++;
			}else{ // 零
				System.out.println("程序结束");
				break;
			}
		
		
		}
		
		System.out.println("正数的个数为:" + positiveCount);
		System.out.println("负数的个数为:" + negativeCount);
		scan.close();
	}
}

# 1.8 嵌套循环

# 基本语法

/*
嵌套循环的使用
1. 嵌套循环:是指一个循环结构 A 的循环体是另一个循环结构 B。
- 外层循环:循环结构 A
- 内层循环:循环结构 B
2. 说明:
1)内层循环充当了外层循环的循环体。
2)对于两层嵌套循环来说,外层循环控制行数,内层循环控制列数。
3)举例:外层循环执行 m 次,内层循环执行 n 次,则内层循环的循环体共执行 m * n 次
4)实际开发中,我们不会出现三层以上的循环结构,三层的循环结构都很少见。
*/
class ForForTest {
	public static void main(String[] args) {
		
		//******
		for(int i = 1;i <= 6;i++){
			System.out.print('*');
		}
		System.out.println("\n##################");
		
		/*
		******
		******
		******
		******
		******
		*/
		
		for(int j = 1;j <= 5;j++){
			for(int i = 1;i <= 6;i++){
				System.out.print('*');
			}
			System.out.println();
		}
		
		/*
						i (第几行)		j (每一行中 * 的个数)
		*				1				1
		**				2				2
		***				3				3
		****			4				4
		*****			5				5
		*/
		for(int i = 1;i <= 5;i++){
			
			for(int j = 1;j <= i;j++){
				System.out.print("*");
			}
			System.out.println();
		
		}
		/*
						i (第几行)		j (每一行中 * 的个数)		i + j = 7 --> j = 7 - i
		******			1				6
		*****			2				5
		****			3				4
		***				4				3
		**				5				2
		*				6				1
		
		*/
		for(int i = 1;i <= 6;i++){
			for(int j = 1;j <= 7 - i;j++){
				System.out.print("*");
			}
			
			System.out.println();
		}
	/*
						i (第几行)	j (每一行中 - 的个数)		k (每一行中 * 的个数)    2*i + j = 10 --->j = 10 - 2*i
--------*				1				8				1                k = 2 * i - 1
------* * *				2				6				3
----* * * * *			3				4				5
--* * * * * * *			4				2				7
* * * * * * * * *		5				0				9
  * * * * * * * 
    * * * * * 
      * * * 
        * 
		
	*/
	// 上半部分
	for(int i = 1;i <= 5;i++){
		// -
		for(int j = 1;j <= 10 - 2*i;j++){
			System.out.print("-");
		}
		// *
		for(int k = 1;k <= 2 * i - 1;k++){
			System.out.print("* ");
		}
		System.out.println();
	}
	}
}

# 案例

/*
练习:九九乘法表
*/
class NineNineTable {
	public static void main(String[] args) {
		
		for(int i = 1;i <= 9;i++){
			
			for(int j = 1;j <= i;j++){
				
				System.out.print(i + "*" + j + "=" + i * j + "\t");
			
			}
			System.out.println();
		
		}
	}
}

# 1.9 关键字 break、continue

  • break 在开发中常用;而 continue 较少使用
  • 笔试题:break 和 continue 的区别。

# 基本语法

/*
1. break 和 continue 关键字的使用
				使用范围			在循环结构中的作用					相同点
break:			switch-case
				循环结构中			结束(或跳出)当前循环结构			在此关键字的后面不能声明执行语句。
continue:		循环结构中			结束(或跳出)当次循环				在此关键字的后面不能声明执行语句。
		
2. 了解带标签的 break 和 continue 的使用
3. 开发中,break 的使用频率要远高于 continue。
*/
class BreakContinueTest{
	public static void main(String[] args){
		
		for(int i = 1;i <= 10;i++){
			if(i % 4 == 0){
				//break;
				continue;
				
				// 编译不通过
				//System.out.println ("今晚上迪丽热巴要约我!");
			}
			
			System.out.print(i);
		
		}
		
		System.out.println();
		//*****************************
		label:for(int j = 1;j <= 4;j++){
		
			for(int i = 1;i <= 10;i++){
				if(i % 4 == 0){
					//break;
					//continue;	
					// 了解
					//break label;
					//continue label;
				}
				
				System.out.print(i);			
			}
			System.out.println();
		
		}
	
	}
}

# 1.10 项目 1:谷粒记账软件

  • 特点 1:代码量更大,逻辑更复杂 ---> 推荐大家一定写一写,而且多写几遍。
  • 特点 2:内部不包含新的知识点。 ---> 不太着急写。

# 1.11 Scanner 类的使用

# 基本语法

/*
如何从键盘获取不同类型(基本数据类型、String 类型)的变量:使用 Scanner 类。
1. 使用 Scanner 获取不同类型数据的步骤
步骤 1:导包 import java.util.Scanner;
步骤 2:提供(或创建)一个 Scanner 类的实例
步骤 3:调用 Scanner 类中的方法,获取指定类型的变量 (nextXxx ())
步骤 4:关闭资源,调用 Scanner 类的 close ()
2. 案例:小明注册某交友网站,要求录入个人相关信息。如下:
请输入你的网名、你的年龄、你的体重、你是否单身、你的性别等情况。
3. Scanner 类中提供了获取 byte \ short \ int \ long \float \double \boolean \ String 类型变量的方法。
   注意,没有提供获取 char 类型变量的方法。需要使用 next ().charAt (0)
*/
// 步骤 1:导包 import java.util.Scanner;
import java.util.Scanner;
class ScannerTest {
	public static void main(String[] args) {
		
		// 步骤 2:提供(或创建)一个 Scanner 类的实例
		Scanner scan = new Scanner(System.in);
		
		System.out.println("欢迎光临你来我往交友网");
		System.out.print("请输入你的网名:");
		// 步骤 3:调用 Scanner 类中的方法,获取指定类型的变量
		String name = scan.next();
		System.out.print("请输入你的年龄:");
		int age = scan.nextInt();
		System.out.print("请输入你的体重:");	
		double weight = scan.nextDouble();
		System.out.print("你是否单身(单身:true;不单身:false):");
		boolean isSingle = scan.nextBoolean();
		System.out.print("请输入你的性别(男\\女):"); 
		char gender = scan.next().charAt(0);
		System.out.println("网名:" + name + ",年龄: " + age + ",体重:" + weight + ",是否单身:" + isSingle + 
			",性别:" + gender);
		System.out.println("注册完成,欢迎继续进入体验!");
		// 步骤 4:关闭资源,调用 Scanner 类的 close ()
		scan.close();
	}
}

# 案例

import java.util.Scanner;
class ScannerExer {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		System.out.println("请输入你的身高:(cm)");
		int height = scan.nextInt();
		System.out.println("请输入你的财富:(以千万为单位)");
		double wealth = scan.nextDouble();
		// 关于是否帅问题,我们使用 String 类型接收
		System.out.println("帅否?(是/否)");
		String isHandsome = scan.next();
		
		// 判断
		if(height >= 180 && wealth >= 1.0 && isHandsome.equals("是")){  // 知识点:判断两个字符串是否相等,使用 String 的 equals ()
			System.out.println("我一定要嫁给他!!!");
		}else if(height >= 180 || wealth >= 1.0 || isHandsome.equals("是")){
			System.out.println("嫁吧,比上不足,比下有余。");
		}else{
			System.out.println("不嫁");
		}
		// 关闭资源
		scan.close();
	}
}

# 1.12 获取随机数

/*
如何获取一个随机数?
1. 可以使用 Java 提供的 API:Math 类的 random () 
2. random () 调用以后,会返回一个 [0.0,1.0) 范围的 double 型的随机数
3. 需求 1:获取一个 [0,100] 范围的随机整数?
   需求 2:获取一个 [1,100] 范围的随机整数?
4. 需求:获取一个 [a,b] 范围的随机整数?
   (int)(Math.random () * (b - a + 1)) + a
*/
class RandomTest {
	public static void main(String[] args) {
		
		double d1 = Math.random();
		System.out.println("d1 = " + d1);
		int num1 = (int)(Math.random() * 101);  //[0.0,1.0) --> [0.0,101.0) --->[0,100]
		System.out.println("num1 = " + num1);
		int num2 = (int)(Math.random() * 100) + 1; //[0.0,1.0) --> [0.0,100.0) --->[0,99] ---> [1,100]
	}
}

# 1.13 体会算法的魅力

  • 基本实现
/*
如何获取一个随机数?
1. 可以使用 Java 提供的 API:Math 类的 random () 
2. random () 调用以后,会返回一个 [0.0,1.0) 范围的 double 型的随机数
3. 需求 1:获取一个 [0,100] 范围的随机整数?
   需求 2:获取一个 [1,100] 范围的随机整数?
4. 需求:获取一个 [a,b] 范围的随机整数?
   (int)(Math.random () * (b - a + 1)) + a
*/
class RandomTest {
	public static void main(String[] args) {
		
		double d1 = Math.random();
		System.out.println("d1 = " + d1);
		int num1 = (int)(Math.random() * 101);  //[0.0,1.0) --> [0.0,101.0) --->[0,100]
		System.out.println("num1 = " + num1);
		int num2 = (int)(Math.random() * 100) + 1; //[0.0,1.0) --> [0.0,100.0) --->[0,99] ---> [1,100]
	}
}
  • 测试性能:方式 1
/*
遍历 100000 以内的所有的质数。体会不同的算法实现,其性能的差别
此 PrimeNumberTest1.java 是实现方式 1
*/
class PrimeNumberTest1 {
	public static void main(String[] args) {
		// 获取系统当前的时间:
		long start = System.currentTimeMillis();
		
		boolean isFlag = true;
		int count = 0;// 记录质数的个数
		for(int i = 2;i <= 100000;i++){ // 遍历 100000 以内的自然数
			
			
			// 判定 i 是否是质数
			for(int j = 2;j < i;j++){
				
				if(i % j == 0){
					isFlag = false;
				}
			
			}
			if(isFlag){
				count++;
			}
			
			// 重置 isFlag
			isFlag = true;
		}
		// 获取系统当前的时间:
		long end = System.currentTimeMillis();
		System.out.println("质数的总个数为:" + count); //9592
		System.out.println("花费的时间为:" + (end - start)); //7209
	}
}
  • 测试性能:方式 2
/*
遍历 100000 以内的所有的质数。体会不同的算法实现,其性能的差别
此 PrimeNumberTest2.java 是方式 2,针对于 PrimeNumberTest1.java 中算法的优化
*/
class PrimeNumberTest2 {
	public static void main(String[] args) {
		// 获取系统当前的时间:
		long start = System.currentTimeMillis();
		
		boolean isFlag = true;
		int count = 0;// 记录质数的个数
		for(int i = 2;i <= 100000;i++){ // 遍历 100000 以内的自然数
			
			
			// 判定 i 是否是质数
			for(int j = 2;j <= Math.sqrt(i);j++){
				
				if(i % j == 0){
					isFlag = false;
					break;// 针对于非质数有效果。
				}
			
			}
			if(isFlag){
				count++;
			}
			
			// 重置 isFlag
			isFlag = true;
		}
		// 获取系统当前的时间:
		long end = System.currentTimeMillis();
		System.out.println("质数的总个数为:" + count); //9592
		System.out.println("花费的时间为:" + (end - start)); //7209 --> 加上 break:659 --> 加上 Math.sqrt ():6
	}
}

# 二、企业真题

# 1. break 和 continue 的作用 (智 * 图)

# 2. if 分支语句和 switch 分支语句的异同之处 (智 * 图)

  • if-else 语句优势
    • if 语句的条件是一个布尔类型值,if 条件表达式为 true 则进入分支,可以用于范围的判断,也可以用于等的判断, 使用范围更广
    • switch 语句的条件是一个常量值(byte,short,int,char, 枚举,String),只能判断某个变量或表达式的结果是否等于某个常量值, 使用场景较狭窄
  • switch 语句优势
    • 当条件是判断某个变量或表达式是否等于某个固定的常量值时,使用 if 和 switch 都可以,习惯上使用 switch 更多,因为 效率稍高当条件是区间范围的判断时,只能使用 if 语句。
    • 使用switch 可以利用 穿透性 ,同时执行多个分支,而 if...else 没有穿透性。

# 3. 什么时候用语句 if,什么时候选用语句 switch (灵伴 * 来科技)

同上

# 4. switch 语句中忘写 break 会发生什么 (北京 * 蓝)

case 穿透

# 5. Java 支持哪些类型循环 (上海 * 睿)

  • for;while;do-while
  • 增强 for (或 foreach),放到集合中讲解

# 6. while 和 do while 循环的区别 (国 * 科技研究院)

  • do-while 至少会执行一次。