Java流程控制
1 用户交互Scanner
- java.util.Scanner 是 java5 的新特征,Scanner 类可以获取用户的输入,由此实现程序和人的交互
- Scanner 类的 next() 和 nextline() 方法可以获取用户输入的字符串。读取前一般需要使用 hasNext() (是否还有下一个) 和 hasNextline() (是否还有下一行) 判断是否还有输入的数据
1.1 next()、nextLine()
package com.bin.scanner;
import java.util.Scanner;
public class Demo01 {
public static void main(String[] args) {
// 创建一个扫描器对象,用于接收键盘数据
// Alt + Enter会让你根据提示补齐代码
Scanner scanner = new Scanner(System.in);
System.out.println("使用 next 方式接收:");
// 判断用户有没有输入字符串
if (scanner.hasNext()) {
// 使用 next 方式接收
String str = scanner.next(); // 程序会等待用户输入完毕
System.out.println("输入的内容为:" + str);
}
/*
使用 next 方式接收:
hello world!
输入的内容为:hello
*/
System.out.println("=============================================");
Scanner scan = new Scanner(System.in);
System.out.println("使用 nextLine 方式接收:");
if (scan.hasNextLine()) {
String s = scan.nextLine();
System.out.println("输入的内容为:" + s);
}
/*
使用 nextLine 方式接收:
hello world!
输入的内容为:hello world!
*/
System.out.println("=============================================");
Scanner scanner1 = new Scanner(System.in);
System.out.println("请输入文本内容:");
String text = scanner1.nextLine();
System.out.println("输出的内容是:" + text);
/*
请输入文本内容:
拿起一颗苹果 咬了一口 我犯了错 天大的错 那又怎么样~
输出的内容是:拿起一颗苹果 咬了一口 我犯了错 天大的错 那又怎么样~
*/
// 凡是属于IO流的类,如果不关闭就会一直占用资源,所以用完就要关掉
scanner.close();
scan.close();
scanner1.close();
}
}
在使用 Scanner 类时,如果先用 nextInt()、nextDouble() 等 nextXxx() 方法读取数据,再使用 nextLine() 读取字符串,可能会出现 nextLine() 直接返回空字符串的现象。
这是因为 nextXxx() 方法不会读取换行符(\n),而 nextLine() 会读取并消费掉换行符。
因此,当用户输入内容并按回车后,next() 读取了内容,但换行符仍留在输入缓冲区中,随后调用 nextLine() 会立即读取这个残留的换行符,从而返回一个空字符串。
解决这个问题的方法是在调用
nextXxx()方法后,手动调用一次nextLine()来清除缓冲区中的换行符:
package com.bin.scanner;
import java.util.Scanner;
public class Demo01 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str = null;
String s = null;
System.out.println("使用 next 方式接收:");
// 判断用户有没有输入字符串
if (scanner.hasNext()) {
// 使用 next 方式接收
str = scanner.next(); // 程序会等待用户输入完毕
System.out.println("输入的内容为:" + str);
}
/*
使用 next 方式接收:
hello world!
输入的内容为:hello
*/
System.out.println("=============================================");
scanner.nextLine(); // 清除换行符
System.out.println("使用 nextLine 方式接收:");
if (scanner.hasNextLine()) {
s = scanner.nextLine();
System.out.println("输入的内容为:" + s);
}
/*
使用 nextLine 方式接收:
hello world!
输入的内容为:hello world!
*/
// 凡是属于IO流的类,如果不关闭就会一直占用资源,所以用完就要关掉
scanner.close();
}
}
1.2 nextInt()、nextFloat()
package com.bin.scanner;
import java.util.Scanner;
public class Demo02 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 键盘接收数据
int i = 0;
float f = 0.0f;
System.out.println("请输入整数:");
if (scanner.hasNextInt()) {
i = scanner.nextInt();
System.out.println("整数数据为:" + i);
} else {
System.out.println("输入的不是整数数据!");
}
System.out.println("请输入小数:");
if (scanner.hasNextFloat()) {
f = scanner.nextFloat();
System.out.println("小数数据为:" + f);
} else {
System.out.println("输入的不是小数数据!");
}
/*
请输入整数:
10
整数数据为:10
请输入小数:
10.8
小数数据为:10.8
*/
/*
请输入整数:
1.1
输入的不是整数数据!
请输入小数:
小数数据为:1.1
*/
scanner.close();
}
}
1.3 计算 总和 和 平均数
package com.bin.scanner;
import java.awt.*;
import java.util.Scanner;
public class Demo03 {
public static void main(String[] args) {
// 输入多个数字,并求其 总和 与 平均数,每输入一个数字用回车确认一次,通过输入非数字来结束输入,并输出执行结果
Scanner scanner = new Scanner(System.in);
// 和
double sum = 0;
// 计算 输入了多少个数字
int count = 0;
System.out.println("请输入数据:");
// 通过循环判断是否还有输入,并对每一次循环进行 求和 和 统计
while (scanner.hasNextDouble()) {
double x = scanner.nextDouble();
count++;
sum += x;
System.out.println("你输入了第" + count + "个数据,当前总和为:" + sum);
}
System.out.println(count + "个数的和为:" + sum);
System.out.println(count + "个数的平均数为:" + (sum / count));
/*
请输入数据:
10
你输入了第1个数据,当前总和为:10.0
20
你输入了第2个数据,当前总和为:30.0
30
你输入了第3个数据,当前总和为:60.0
40
你输入了第4个数据,当前总和为:100.0
50
你输入了第5个数据,当前总和为:150.0
#
5个数的和为:150.0
5个数的平均数为:30.0
*/
scanner.close();
}
}
2 顺序结构
- Java 的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行
- 顺序结构是最简单的算法结构
package com.bin.structure;
// 顺序结构
public class SequentialDemo {
public static void main(String[] args) {
System.out.println("Hello1");
System.out.println("Hello2");
System.out.println("Hello3");
System.out.println("Hello4");
System.out.println("Hello5");
}
}
3 选择结构
3.1 if 单选择结构
package com.bin.structure;
import sun.nio.cs.ext.ISO2022_CN_CNS;
import java.util.Scanner;
public class IfDemo01 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入内容:");
String s = scanner.nextLine();
// equals:判断字符串是否相等
if(s.equals("Hello")){
System.out.println(s);
}
System.out.println("End");
/*
请输入内容:
Hello
Hello
End
*/
/*
请输入内容:
hello
End
*/
scanner.close();
}
}
3.2 if 双选择结构
package com.bin.structure;
import java.util.Scanner;
public class IfDemo02 {
public static void main(String[] args) {
// 考试分数大于 60 分及格,小于 60 分不及格
Scanner scanner = new Scanner(System.in);
System.out.println("请输入成绩:");
int score = scanner.nextInt();
if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
/*
请输入成绩:
60
及格
*/
/*
请输入成绩:
33
不及格
*/
scanner.close();
}
}
3.3 if 多选择结构
package com.bin.structure;
import java.util.Scanner;
/*
if 语句至多有 1 个 else 语句,在所有 else if 语句之后
一旦其中一个 else if 语句为 true,其它的 else if 以及 else 语句都将跳过执行
*/
public class IfDemo03 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入成绩:");
int score = scanner.nextInt();
if (score == 100) {
System.out.println("恭喜满分!");
} else if (score < 100 && score >= 90) {
System.out.println("A级");
} else if (score < 90 && score >= 80) {
System.out.println("B级");
} else if (score < 80 && score >= 70) {
System.out.println("C级");
} else if (score < 70 && score >= 60) {
System.out.println("D级");
} else if (score < 60 && score >= 0) {
System.out.println("不及格");
} else {
System.out.println("成绩不合法");
}
/*
请输入成绩:
120
成绩不合法
请输入成绩:
100
恭喜满分!
请输入成绩:
96
A级
请输入成绩:
88
B级
请输入成绩:
74
C级
请输入成绩:
61
D级
请输入成绩:
43
不及格
*/
scanner.close();
}
}
3.4 嵌套的 if 结构
- 如果想寻找 1-100 之间的一个整数,可以先把 1-100 分成 1-50 和 51-100,再把 1-50 和 51-100 两个分类 分别 划分成两部分,以此类推。
- 这个过程就用到了嵌套的 if 结构。
3.5 switch 多选择结构
- switch case 语句判断 一个变量 与 一系列值中某个值 是否相等,每个值称为 一个分支。
- switch 语句中的变量类型可以是:byte、short、int 或 char;从 JDK7 开始,switch 支持 字符串 String 类型。此外,case 标签必须为 字符串常量 或 字面量。
3.5.1 switch case 代码示例
package com.bin.structure;
public class SwitchDemo01 {
public static void main(String[] args) {
// switch 匹配一个具体的值
// case 穿透
// 只在 case'A' 后面加了 break;
// char grade = 'C';
/*
及格
再接再厉
挂科
未知等级
*/
// char grade = 'F';
/*
未知等级
*/
// char grade = 'A';
/*
优秀
*/
// 每种情况后都加了 break;
char grade = 'D';
/*
再接再厉
*/
switch(grade){
case 'A':
System.out.println("优秀");
break; // 如果不加 break,后面的情况会继续输出
case 'B':
System.out.println("良好");
break;
case 'C':
System.out.println("及格");
break;
case 'D':
System.out.println("再接再厉");
break;
case 'E':
System.out.println("挂科");
break; // 可选
default:
System.out.println("未知等级");
}
}
}
package com.bin.structure;
public class SwitchDemo02 {
public static void main(String[] args) {
String name = "橘子";
/*
橘子
*/
// String name = "橙子";
/*
橙子
*/
// String name = "苹果";
/*
什么东西???
*/
// 字符的本质还是数字
// 反编译 java --(编译)--> class(字节码文件,人类看不懂,需要反编译)--(反编译,IDEA)-->
switch (name){
case "橙子":
System.out.println("橙子");
break;
case "橘子":
System.out.println("橘子");
break;
default:
System.out.println("什么东西???");
}
}
}
3.5.2 如何用 IDEA 对 指定文件 实现反编译
- 字符的本质还是数字
- 反编译 java --(编译)--> class(字节码文件,人类看不懂,需要反编译)--(反编译,IDEA)-->
-
点击项目结构
-
复制项目编译后的输出路径
-
在资源管理器的地址栏粘贴输出路径,查看 production 文件夹
-
一路点击直到查找到指定的某一执行的class文件,右键选择“以 Notepad++ 编辑”,发现都是乱码
-
在 IDEA 左侧项目栏右键某一个包,选择“Show in Explorer”
-
把第 4 条中想要反编译的 class 文件拖动到第 5 条的文件夹下,即可在 IDEA 左侧项目栏的对应位置看到该 class 文件
- name变成了name.hashCdoe(),通过哈希值比较
4 循环结构
4.1 while 循环
- 只要布尔表达式为 true,循环就会一直执行下去,会造成死循环,影响程序性能或程序卡死崩溃。正常的业务编程中应尽量避免死循环
- 大多数情况需要循环停下来,对应地就要有一个让表达式失效的方式来结束循环
- 少部分情况需要循环一直执行,比如服务器的请求响应监听
package com.bin.structure;
public class WhileDemo01 {
public static void main(String[] args) {
// 输出 1~100
int i = 0;
while (i < 100) {
i++;
System.out.println(i);
}
// 死循环
while (true){
// 等待客户端连接
// 定时检查
// ......
}
}
}
package com.bin.structure;
public class WhileDemo02 {
public static void main(String[] args) {
// 计算 1 + 2 + 3 + ... + 100 = ?
int i = 0;
int sum = 0;
while (i < 100) {
i++;
sum += i;
/*
sum += i;
i++;
*/
}
System.out.println(sum); // 5050
}
}
4.2 do...while 循环
- 对于 while 语句而言,如果不满足条件,则不能进入循环;但有时需要即使不满足条件,也至少执行一次,此时就可以运用 do...while 循环
- while 和 do...while 的区别:
- while 先判断后执行,do...while 先执行后判断
- do...while 总是保证循环体至少被执行一次
package com.bin.structure;
public class DoWhileDemo01 {
public static void main(String[] args) {
int i = 0;
int sum = 0;
do {
sum += i;
i++;
} while (i <= 100);
/*
do {
i++;
sum += i;
} while (i < 100);
*/
System.out.println(sum); // 5050
}
}
package com.bin.structure;
public class DoWhileDemo02 {
public static void main(String[] args) {
int a = 0;
while (a < 0) {
System.out.println(a);
a++;
} // 不输出内容,没进入循环体
System.out.println("=======================");
do {
System.out.println(a);
a++;
} while (a < 0); // 0
/*
=======================
0
*/
}
}
4.3 for 循环
- for 循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构
- for 循环执行的次数是在执行前就确定的
- 关于 for 循环的流程:
- 执行初始化步骤。可以声明一种类型,但可初始化一个或多个循环控制变量,也可以是空语句
- 检测布尔表达式的值。若为 true,则循环体被执行;若为 false,则循环终止,开始执行循环体后的语句
- 执行一次循环后,更新循环控制变量(迭代因子控制循环变量的增减)
- 再次检测布尔表达式,循环执行 1~3 的过程
package com.bin.structure;
public class ForDemo01 {
public static void main(String[] args) {
int a = 1; // 初始化条件
while (a <= 100) { // 条件判断
System.out.println(a); // 循环体
a += 2; // 迭代
}
System.out.println("while循环结束!");
System.out.println("=======================");
// 初始化 // 条件判断 // 迭代
for (int i = 1; i <= 100; i += 2) {
System.out.println(i);
}
System.out.println("for循环结束!");
// 100.for 敲回车,自动生成 for循环语句
for (int i = 0; i < 100; i++) {}
/*
关于 for 循环的流程:
1. 执行初始化步骤。可以声明一种类型,但可初始化一个或多个循环控制变量,也可以是空语句
2. 检测布尔表达式的值。若为 true,则循环体被执行;若为 false,则循环终止,开始执行循环体后的语句
3. 执行一次循环后,更新循环控制变量(迭代因子控制循环变量的增减)
4. 再次检测布尔表达式,循环执行 1~3 的过程
*/
// 死循环
for ( ; ; ){}
}
}
4.3.1 计算 1~100 的奇数和、偶数和
package com.bin.structure;
public class ForDemo02 {
public static void main(String[] args) {
// 练习 1:计算 0 到 100 之间的 奇数和 与 偶数和
int oddSum = 0;
int evenSum = 0;
for (int i = 0; i <= 100; i++) {
if (i % 2 != 0) { // 奇数
oddSum += i;
} else { // 偶数
evenSum += i;
}
}
System.out.println("奇数的和:" + oddSum);
System.out.println("偶数的和:" + evenSum);
// 奇数的和:2500
// 偶数的和:2550
}
}
4.3.2 输出 1~1000 之间能被 5 整除的数,并且每行输出 3 个
package com.bin.structure;
public class ForDemo03 {
public static void main(String[] args) {
// 练习 2:用 while 或 for 循环输出 1~1000 之间能被 5 整除的数,并且每行输出 3 个
// for 循环
for (int i = 1; i <= 1000; i++) {
if (i % 5 == 0) {
System.out.print(i + "\t");
}
if (i % (5 * 3) == 0) { // 换行
System.out.println();
// System.out.print("\n");
}
}
// println 输出完会换行
// print 输出完不会换行
// while 循环
// int i = 1;
// while (i <= 1000) {
// if (i % 5 == 0) {
// System.out.print(i + "\t");
// }
// if (i % (5 * 3) == 0) {
// System.out.print("\n");
// }
// i++;
// }
}
}
4.3.3 打印九九乘法表
package com.bin.structure;
public class ForDemo04 {
public static void main(String[] args) {
// 练习 4:打印九九乘法表
for (int i = 1; i <= 9; i++) { // 第 i 行
for (int j = 1; j <= i; j++) { // 第 j 列
System.out.print(j + "*" + i + "=" + (i * j) + "\t");
}
System.out.println();
}
/*
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
*/
}
}
4.3.4 增强 for 循环
- 在 JDK5 中引入了一种 主要用于数组或集合的 增强型 for 循环
- 声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等
- 表达式:表达式是要访问的数组名,或者是返回值为数组的方法
package com.bin.structure;
public class ForDemo05 {
public static void main(String[] args) {
int[] numbers = {10, 20, 30, 40, 50}; // 定义一个数组
for (int i = 0; i < 5; i++) {
// 下标为 i 的数,即第 i 个数 比如 numbers[0] 是第一个数
System.out.println(numbers[i]);
}
System.out.println("===========================");
// 遍历数组元素
// 增强 for 循环
// 声明语句 : 表达式
for (int x : numbers) {
System.out.println(x);
}
/*
10
20
30
40
50
===========================
10
20
30
40
50
*/
}
}
5 break & continue
package com.bin.structure;
public class BreakDemo {
public static void main(String[] args) {
int i = 0;
// break 用于强行退出循环
while (i < 100) {
i++;
System.out.println(i);
if (i == 5) {
break;
}
}
System.out.println("还能接着执行,只是跳出循环体了");
/*
1
2
3
4
5
还能接着执行,只是跳出循环体了
*/
System.out.println("============================");
int j = 0;
// continue 用于终止某次循环过程
while (j < 10) {
j++;
if (j % 2 != 0) { // 为了排除掉该情况(奇数)
// System.out.println();
continue;
}
System.out.println(j);
}
System.out.println("只跳过循环体中符合条件的语句");
/*
2
4
6
8
10
只跳过循环体中符合条件的语句
*/
}
}
package com.bin.structure;
public class LabelDemo {
public static void main(String[] args) {
// 打印 101~150 之间所有的质数
// 质数:在大于 1 的自然数中,除了 1 和它本以外不再有 其他因数 的自然数
// 操作很麻烦,了解就好,不建议使用
outer: // 这是一个标签,用来标识外层循环。有 goto 语言的影子
for (int i = 101; i <= 150; i++) {
// 任何大于 1 的数都能被 1 和它本身整除,所以只需要检查从 2 开始到这个数本身减 1 之间的数是否能整除它。
// 如果一个数 i 有大于 i/2 的因数,那么必然有一个小于 i/2 的因数与之对应。
// 例如,如果 i = 10,它的因数有 1, 2, 5, 10。其中大于 5(即 i/2)的因数只有 10,而它对应的较小因数是 1。因此,只需要检查到 i/2 就足够了。
// 从 2 开始检查到 i/2,看能不能整除 i
for (int j = 2; j < i / 2; j++) {
// 如果 i 能被 j 整除,说明 i 不是质数
if (i % j == 0) {
// 使用 continue outer 跳过这次内层循环,继续外层循环检查下一个数
continue outer;
}
}
System.out.print(i + " ");
}
// 101 103 107 109 113 127 131 137 139 149
}
}
6 练习:打印三角形
package com.bin.structure;
public class TestDemo {
public static void main(String[] args) {
// 打印三角形 5行
for (int i = 1; i <= 5; i++) {
for (int j = 5 - i; j > 0; j--) {
System.out.print(" ");
}
for (int j = 1; j <= 2 * i - 1; j++) {
System.out.print("*");
}
System.out.println();
}
System.out.println("==================================");
for (int i = 1; i <= 5; i++) {
for (int j = 5; j >= i; j--) {
System.out.print(" ");
}
// for (int j = 5; j > i; j--) {
// System.out.print(" ");
// }
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
for (int j = 1; j < i; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
-
如果不清楚某步骤是如何运行的,可以先单击该语句前面的代码行序号,再点击 Debug,点击蓝色的 **Step Over ** 可以看每一步都是如何执行的
![image-20260325194350206]()

浙公网安备 33010602011771号