javaSE10-流程控制
在程序中,程序运行的流程控制决定着程序是如何执行的,是我们必须掌握的,主要有三大流程控制语句:顺序控制、分支控制、以及循环控制。
1.顺序控制
1.1 示意图
java的默认基本结构就是顺序结构,即程序由上而下逐行地执行,中间没有任何判断和跳转。程序执行流程图如下:
1.2 举例及注意事项
java中定义变量时采用合法的前向引用。
public class Text{
public static void main (String[] args){
//正确形式,先定义再使用
int num1 = 1;
int num2 = num1 + 1;
//错误形式
int num4 = num3 + 1; //错误,使用num3时 num3还未定义
int num3 = 1;
}
}
2.分支控制 if-else
让程序有选择的进行,分为单分支、双分支、多分支三种类型。
2.1单分支
单分支控制运行示意图如下所示:
2.1.1 语法结构
public class ifDemo01 {
public static void main (String[] args){
// 单分支 if
if (布尔表达式){
//如果布尔表达式为true将执行的语句
代码块1
}
}
}
2.1.2 案例
使用Scanner扫描器接受用户输入的信息,如果用户输入信息则将其打印出来。
import java.util.Scanner;
public class ifDemo02 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您想说的话:");
// 判断用户是否输入了信息
if (scanner.hasNextLine()){
// 如果是则将其打印出来
String str = scanner.nextLine();
System.out.println("输出的内容为:"+str);
}
scanner.close();
}
}
2.2 双分支
当有两个判断时,可以使用双分支控制(if else),运行原理如下:
2.2.1 语法结构
public class Text{
public static void main (String[] args){
// 双分支 if-else
if (布尔表达式){
//如果布尔表达式为true 将执行的语句
代码块1
}
else {
//如果布尔表达式为false 将执行的语句
代码块2
}
}
}
2.2.2 案例
来看看谁是世界上最帅的人。
import java.util.Scanner;
public class ifDemo03 {
public static void main(String[] args) {
Scanner scannr = new Scanner(System.in);
System.out.println("谁是世界上最帅的人:");
String s = scannr.nextLine();
// equals 判断字符串是否相当
if (s.equals("锅里飞") ){
System.out.println("真有眼光!"+ " " + s +" " +"最厉害。");
}
else System.out.println("你好好反思一下!");
scannr.close();
}
}
2.3 多分支
拥有多个选择时,可使用多分支控制,关键字 (if else if else),多分支控制只能有一个运行入口,运行原理如下:
2.3.1 语法结构
public class Text{
public static void main (String[] args){
// 多分支 if-else if -else
if (布尔表达式1){
//如果布尔表达式1为true 将执行的语句
语句代码块1
}
else if (布尔表达式2){
//如果布尔表达式2为true 将执行的语句
语句代码块2
}
else {
//如果均不为上述情况 将执行的语句
语句代码块n
}
}
}
2.3.2 案例
根据用户输入的成绩判断成绩等级。
import java.util.Scanner;
public class ifDemo04 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您的成绩:");
Double score = scanner.nextDouble();
if (score<60 && 0<=score){
System.out.println("成绩不合格!");
}
else if (60<= score && score <80){
System.out.println("成绩合格!");
}
else if (80<= score && score <90){
System.out.println("成绩良好!");
}
else if (90<= score && score <100){
System.out.println("成绩优秀!");
}
else if (score ==100){
System.out.println("真棒,满分!");
}
else System.out.println("成绩不合法!");
}
}
2.4 嵌套分支
判断中嵌套判断,在一个完整的分支结构中又嵌套了另一个完整的分支结构,里面的分支结构称为内层分支,外面的分支结构成为外层分支。注意:分支嵌套不要超过三层,可读性不好。
2.4.1 语法结构
public class Text{
public static void main (String[] args){
// 嵌套分支
// 外层分支
if (布尔表达式1){
// 内层分支
if (布尔表达式2){
// 如果布尔表达式2为true 将执行的语句
语句代码块1
}
else {
// 如果布尔表达式2为false 将执行的语句
语句代码块2
}
}
else {
// 如果布尔表达式1为false 将执行的语句
语句代码块3
}
}
}
2.4.2 案例
参加歌手比赛,如果成绩大于8.0则进入决赛,否则提示淘汰,并根据性别提示进入男子组或者女子组。[可以让学员先练习一下],输入成绩和性别,进行判断和输出信息。
import java.util.Scanner;
public class ifDemo05 {
public static void main(String[] args) {
Scanner scannerScore = new Scanner(System.in);
System.out.println("请输入成绩");
double score = scannerScore.nextDouble();
if (score > 8.0 ){
System.out.println("恭喜进入决赛!");
Scanner scannerGender = new Scanner(System.in);
System.out.println("========================");
System.out.println("请输入性别");
char gender = scannerGender.nextLine().charAt(0);
if (gender == '男'){
System.out.println("请进入男子组参加比赛。");
}
else if (gender == '女'){
System.out.println("请进入女子组参加比赛。");
}
else System.out.println("性别未被登记!下次再来吧哈哈哈!");
scannerGender.close();
}
else System.out.println("很抱歉,你被淘汰了!");
scannerScore.close();
}
}
3.分支控制 switch
关键词 switch-case-default ; 每写完一个case ,都在后面补充一个break(防止case穿透)。可以用来比较字符(char),jdk7以后可以比较字符串(String)。
3.1 语法结构
public class Text{
public static void main (String[] args){
// 多分支 switch - case - default
// switch 关键字 表示一个switch分支
// 表达式对应一个值
Switch (表达式){
// 当表达式的值为常量1时,执行代码块1
case(常量1):
//常量1下所执行的代码语句块
代码语句块1
//退出,防止case穿透
break;
// 当表达式的值为常量2时,执行代码语句块2
case(常量2):
//常量2下所执行的代码语句块
代码语句语句块2
//退出,防止case穿透
break;
//其余情况下 所执语句行的代码语句块
default:
代码语句块n
break;//可选
}
}
}
3.2 案例
public class SwitchDemo01 {
public static void main(String[] args) {
char grade = 'C';
switch (grade){
case 'D':
System.out.println("成绩不合格!");
break;
case 'C':
System.out.println("成绩合格!"); //输出成绩合格
break;
case 'B':
System.out.println("成绩优秀!");
break;
case 'A':
System.out.println("满分!");
break;
default:
System.out.println("成绩不合法!");
}
}
}
3.3 注意事项
3.3.1 数据类型一致
表达式数据类型应与case后面的常量类型保持一致,或者是可以自动转换成可以互相比较的类型,比如输入的字符,而常量是int。
3.3.2 表达式返回数据类型特定
switch(表达式)中表达式的返回值必须是:byte、short、int、char、eunm、String类型。例:
double c = 1.1;
switch (c){ //错误 c为double类型,而switch(表达式)中表达式的返回值必须是:byte、short、int、char、eunm、String类型,无法自动转换。
case 1.1:
System.out.println("hello");
break;
}
3.3.3 case值必须为常量或常量表达式
case中的值必须是常量或常量表达式(1,‘a’,‘a’+1)而不能是变量。
double c = 'a';
switch (c){
case c:// 错误,c为变量,case中的值必须是常量或常量表达式(1,'a','a'+1)
System.out.println("hello");
break;
}
3.3.4 default为可选的,不是必须要有的。
default语句为可选的,当没有与之匹配的case时,就会执行default。即用于处理case之外的情况。
3.3.5 break
break语句用于执行完一个case分支后使程序跳出switch语句,如果没有写break,就会发生case穿透现象,程序会按照循序执行到switch结尾,除非遇到break。
public class SwitchDemo02 {
public static void main(String[] args) {
char grade = 'D';
switch (grade){
case 'D':
System.out.println("成绩不合格!"); // 输出成绩不合格
// 程序继续执行
case 'C':
System.out.println("成绩合格!"); // 输出 成绩合格
// 程序继续执行
case 'B':
System.out.println("成绩优秀!"); // 输出成绩优秀
break; // 遇到break 跳出switch语句,执行后续命令。
case 'A':
System.out.println("满分!");
default:
System.out.println("成绩不合法!");
}
System.out.println("退出switch"); //输出 退出switch
}
}
3.3.6 case后判断的依据为hashcode值
通过对.class文件的反编译,可以得知switch中是以hashcode为标准判断条件是否一致。
4 switch与if-else语句的比较
4.1 适用switch
如果判断的具体数值不多,且符合byte、short、int、char、eunm、String类型时,使用switch。
4.2 适用if-else
其他情况,比如对于Boolean值,以及对于区间的判断,使用if语句,if语句的使用范围更广。
5 for循环控制
for循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构。for循环控制运行原理如下:
5.1 语法结构
for循环的循环次数是在执行前就确定的,语法格式为:
for(循环变量初始化;布尔表达式-循环条件;更新-循环变量迭代){
//循环代码语句 可以为多条语句
//当循环代码语句只有一句时,可以省略{},建议不要省略。
}
5.2 注意事项
5.2.1 循环条件的返还值一定为布尔值。
5.2.2 for( ;循环判断条件; )
for( ;循环判断条件; )中变量的初始化和迭代可以写到其他地方,但是两边的括号不能省略。
- 例:
public class forDemo {
public static void main(String[] args) {
//初始化变量
// i在for循环外定义后可以在for循环结束之后继续使用
int i = 0;
// 循环条件,但分号不能省略
for ( ;i < 10 ; ){ // i定义在for循环中时,只在for循环起作用,循环外无法调用(作用域只在for循环内)
// 循环操作
System.out.println("加油啊!");
// 变量迭代
i++;
}
System.out.println("i= " + i); // i = 10;
}
}
5.2.3 for( ; ; )
for( ; ; )代表一个无限循环/死循环,因为没有初始值和判断条件,循环会一直进行。
5.2.4 循环变量的初始化可以有多条初始化语句,但要求类型一样,并且中间用逗号隔开。
5.2.5 循环变量的迭代也可以有多条变量迭代语句,同样需要用逗号隔开。
例:
public class forDemo {
public static void main(String[] args) {
int count = 3;
for (int i = 0,j = 0 ;i < count ; i++,j+=2){
System.out.println("i="+i + "j="+j); // i=0 j=0, i=1 j=2 , i=2 j=4
}
}
}
5.3 案例
-
化简为繁:将复杂的需求分解为简单的需求,然后逐步实现。
-
先死后活:想考虑固定的值,然后转化成灵活的区间。
5.3.1 案例01
计算0~100之间的奇数和与偶数和;
public class forDemo01 {
//计算0-100之间的奇数和与偶数和
public static void main(String[] args){
int i = 0;//定义遍历0-100之间的参数,同时初始化参数
int sum1 = 0;//定义偶数之和,同时初始化参数
int sum2 = 0;//定义奇数之和,同时初始化参数
for(i=0;i<=100;i++){//判断循环条件
if(i%2==0){//判断偶数条件
sum1 = sum1 + i;//偶数求和
}
else sum2 = sum2 + i;//奇数求和
}
System.out.println("0-100之间的偶数和为:"+sum1);//输出结果
System.out.println("0-100之间的奇数和为:"+sum2);//输出结果
}
}
5.3.2 案例02
输出1-1000之间能被5整除的数,并且每行输出3个;
public class forDemo02 {
//for循环输出0-1000以内能够被5整除的数,并且每行输出3个
public static void main(String[] args) {
for (int i=0;i<=1000;i++){//1000.for 定义遍历0-1000之间的参数,同时初始化参数
if (i%5==0){//被5整除
System.out.print(i+" "); // println为隔行打印,每输出一个就换一行 print为单行打印
}
//难点 每行输出3个
if (i%15==0) {//每3个被5整除的数
System.out.println();//换行(输出一个空白行)
}
}
}
}
5.5 增强for循环
5.5.1 增强for循环是jdk5引入的一种用于数组或集合的增强型for循环
5.5.2 语法结构:
for(声明语句:表达式){
代码
}
5.5.3 声明语句
用于声明新的局部变量,该变量的类型必须和数组元素的类型匹配,其作用域限定在循环语句块,其值与此时的数组元素的值相等。
5.5.4 表达式
表达式是要访问的数组名,或者是返回值为数组的方法
6 while循环
6.1语法结构
while 循环为最基本的循环结构,while循环也有四要素,只不过四要素放置的位置不一样。其语法结构为:
循环变量初始化
while (循环条件-布尔表达式){
//循环内容
循环体(语句)
循环变量迭代
}
- 例:
public class WhileDemo {
public static void main(String[] args) {
// 输出1~100
int i = 0 ;
while (i<100){//注意i<100 与 i<=100
i++;
System.out.println(i);
}
}
}
6.2 注意事项
6.2.1 只要布尔表达式结果为true,循环就会一直下去。
6.2.2 大多数情况是要让循环停止下来的,我们需要一个让表达式失效的方式来结束循环。
6.2.3 少部分情况需要程序一直执行,比如服务器请求响应监听等。
6.2.4 循环条件一直为true就会造成无限循环(死循环),我们正常的业务中应该尽量避免死循环,会影响计算机性能或者造成程序卡死崩溃。
6.3 案例
输出1+2+3+4+…+100的结果为多少?
public class WhileDemo {
public static void main(String[] args) {
//1+2+3+4+...+100=?
//初始化变量
int i = 0;// 记数
int sum = 0;// 计和
while (i<=100){
sum = sum + i;
i++;
}
System.out.println(sum);
}
}
7 do while循环
do while循环与while循环类似,不同的是,即使不满足条件,do while循环也会执行一次。
7.1 语法结构
对于while循环而言,如果不满足条件,则不能进入循环。但有时候即使不满足条件,程序也要执行一次。其基本语法结构为:
循环变量初始化
do {
//执行的命令语句
循环体语句
循环变量迭代
}while(循环条件-布尔表达式);// 最后有一个分号
7.2 注意事项
7.2.1 do while 循环是关键字
7.2.2 while语句后面有一个分号。
7.2.3 while 与do while之间的区别
- 对于while循环而言,如果不满足条件,则不能进入循环。
- do whlie是先保证循环会至少被执行一次,然后再判断是否接着循环!
7.3 案例
利用do while循环输出0-100之间的所有数。
public class DoWhileDemo {
public static void main(String[] args) {
int count = 0; // 作用域在整个方法中
do {
// int count = 0 ,作用域仅在do{}代码块中,while中无法读取
System.out.println("当前的数字count为"+count++);
}while (count <= 100);
}
}
8 嵌套循环
8.1 注意事项
- 将循环放在另一个循环体内,就形成了嵌套循环,其中for、while、do
while均可作为外层循环和内层循环。建议一般使用两层,最多不要超过三层,否则代码可读性很差。 - 当实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为 false
时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环。 - 设外层循环次数为 m 次,内层为 n 次,则内层循环体实际上需要执行 m*n 次。
8.2 案例
8.2.1 案例01
打印九九乘法表。
public class forDemo03 {
//打印九九乘法表
//规律:每一行的最大值为1-9,每一行的第一个因数为1-n(n为每一行的最大值/第几行)
//有两个因数,所以有两个变量
public static void main(String[] args) {
//遍历1-9 10.for,把0-->1 ,i为列数
for (int i = 1; i < 10; i++) {
//再次遍历1-9 10.for,把0-->1 ,j为行数
for (int j = 1; j <=i; j++) {//防止重复 j<=i
System.out.print(j+"×"+i+"="+j*i+" ");
if (j==i){//当最后一个算式为 两因数相同时,换行
System.out.println();
}
}
}
}
}
输出结果:
8.2.2 案例02
打印金字塔
public class forDemo04 {
public static void main(String[] args) {
// 定义行数
int m;
// 定义每行输入的“ ”数
int i;
// 定义每行输入的“*”数
int j;
// 循环1 最外层循环,控制金字塔共有多少层,同时在每层输入完毕后进行换行,这里以5层金字塔为例。
for (m = 1; m <= 5; m++) {
// 循环2-内循环 控制金字塔“*”之前的空格数量,与金字塔层数有关。以5层金字塔为例:
// 第一层 4个 ==> 1...4
// 第二层 3个 ==> 2...3
// 第三层 2个 ==> 3...2
// 第四层 1个 ==> 4...1
// 第五层 0个 ==> 5...0
// 规律总结 :第几层数+"*"前空格数= 总层数
for (i = 0; i + m < 5; i++) {
System.out.print(" ");
}
// 循环3-内循环,控制金字塔中“*”的数量,与金字塔层数有关。以5层金字塔为例:
// 第一层 1个 ==> 1...1
// 第二层 3个 ==> 2...3
// 第三层 5个 ==> 3...5
// 第四层 7个 ==> 4...7
// 第五层 9个 ==> 5...9
// 规律总结 :"*"数= 2m-1 (m表示第几层)
for (j = 0; j <(2*m-1); j++) {
System.out.print("*");
}
// 每层内容输出完毕后换行
System.out.println();
}
}
}
运行结果:
9 跳转控制语句-break
跳转控制语句的作用是当某个条件被满足时,终止循环,通过该需求可以说明其他流程控制数据的必要性。
9.1 语法结构
break语句用于终止某个语句块的执行,一般用在switch或者循环(for、while)中,其基本语法如下:
{ ......
break;
......
}
- 例:
public class breakDemo01 {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
if (i == 3){
break; // 满足条件时吗,跳出for循环
}
System.out.println("i="+i);// i=0; i=1; i=2;
}
}
}
9.2 注意事项
9.2.1 指定退出(层)
break语句出现在多层嵌套的语句块时,可以通过标签指明要终止的是哪一层语句块。标签的基本使用:
lable1:{
语句块1
lable2:{
语句块1
label3:{
......
break lable2;
......
}
......
}
}
9.2.2 标签的使用
- lable1/2/3 (满足标识符命名规则,可以随便使用abc1/2/3)为标签,由程序员指定。在break后指定哪个标签就退出到哪里。
- 在实际的开发中尽量不要使用标签。
- 如果没有指定break退出的层级,那么就会默认退出最近的循环体。
- 例:
public class breakDemo02 {
public static void main(String[] args) {
lable1:// 定义外层循环标签
for (int j = 0; j < 4; j++) {
lable2:// 定义内层循环标签
for (int i = 0; i < 10; i++) {
if (i==2){
break lable1; // 当i=2时,退出lable1,外层循环,程序结束
}
System.out.println("i="+i); // i=0;i=1。
}
}
}
}
输出结果:
- 改变标签,输出结果发生变化:
public class breakDemo03 {
public static void main(String[] args) {
lable1:// 定义外层循环标签
for (int j = 0; j < 4; j++) {
lable2:// 定义内层循环标签
for (int i = 0; i < 10; i++) {
if (i==2){
break; // 默认退出最近的循环体(lable2,内层循环 ),继续外层循环,结果循环输出四次
}
System.out.println("i="+i); // i=0;i=1。
}
}
}
}
输出结果为:
10 跳转控制语句-continue
10.1 语法结构
continue语句用于结束本次循环,继续执行下一次循环。与break不同之处在于break为退出循环,continue为跳过本次循环,执行下一次循环。 其基本语法为:
{
...
continue;
...
}
- 例:
public class continueDemo01 {
public static void main(String[] args) {
int i = 1;
while (i <= 4 ){
i++;
if(i == 2){
continue; // i=2时,跳出本次循环,不执行下面的语句,重新开始循环
}
System.out.println("i="+i); // i=3,i=4,i=5
}
}
}
输出结果:
10.2 注意事项
continue同样可以通过标签来指定下一次循环的层级,如果未指定跳过循环的层级,那么就会默认跳过最近的循环体。
- 例:
public class continueDemo02 {
public static void main(String[] args) {
lable1: // 定义外层循环标签
for (int j = 0; j < 4; j++) {
lable2://定义内层循环标签
for (int i = 0; i < 10; i++) {
if (i == 2){
continue;// 未指定层级,默认跳出最近循环体(lable2,内层循环)i=2时,跳过本次内层循环,不执行后续语句,不输出i=2,继续执行下次内层循环。
}
System.out.println("i="+i);
}
}
}
}
输出结果:(输出两次0-9,排除2)
- 改变标签:
public class continueDemo03 {
public static void main(String[] args) {
lable1://定义外层循环标签
for (int j = 0; j < 4; j++) {
lable2://定义内层循环标签
for (int i = 0; i < 10; i++) {
if (i==2){
continue lable1; // i=2时,跳出本次lable2所代表的循环(外层循环),执行下次外层循环
}
System.out.println("i="+i); // i=0,i=1
}
}
}
}
输出结果:(输出两次0,1)
11 跳转控制语句-return
return语句在方法中使用(在讲解方法时详解),表示跳出所在的方法,如果return写在main方法中,则表示退出程序。
- 例:
public class returnDemo01 {
public static void main(String[] args) {
for (int i = 0; i <= 5; i++) {
if (i == 3 ){
System.out.println("小锅加把劲"+i); // i=3 时,输出 “小锅加把劲+3”,同时退出程序,不会执行方法中的后续语句,不会输出 “加油哈”
return;
}
System.out.println("下次一定"); // i=0、1、2时,输出“下次一定”
}
System.out.println("加油哈");// 退出方法后不会输出
}
}
输出结果如下: