前文
本章是关于Java流程控制语句的最全汇总,本篇为汇总中篇。
流程是人们生活中不可或缺的一部分,它表示人们每天都在按照一定的流程做事。
比如出门搭车、上班、下班、搭车回家。这其中的步骤是有顺序的。
程序设计也需要有流程控制语句来完成用户的要求,根据用户的输入决定程序要进入什么流程,即“做什么”以及“怎么做”等。
从结构化程序设计角度出发,程序有 3 种结构:顺序结构、选择结构和循环结构。
若是在程序中没有给出特别的执行目标,系统则默认自上而下一行一行地执行该程序,这类程序的结构就称为顺序结构。
到目前为止,我们所编写的程序都属于顺序结构。
但是事物的发展往往不会遵循早就设想好的轨迹进行,因此,所设计的程序还需要能够具有在不同的条件下处理不同问题以及当需要进行一些相同的重复操作时,如何能省时省力地解决问题的能力。
在本章中,我们将对 Java 程序中的上述3种流程结构进行学习。
初学者应该对本章的每个小节进行仔细阅读、思考,这样才能达到事半功倍的效果。
Java switch case语句详解
if…else 语句可以用来描述一个“二岔路口”,我们只能选择其中一条路来继续走,然而生活中经常会碰到“多岔路口”的情况。
switch 语句提供了 if 语句的一个变通形式,可以从多个语句块中选择其中的一个执行。
switch 语句格式
switch 语句是 Java 的多路分支语句。
它提供了一种基于一个表达式的值来使程序执行不同部分的简单方法。
因此,它提供了一个比一系列 if-else-if 语句更好的选择。
switch 语句的基本语法形式如下所示:
switch(表达式) { case 值1: 语句块1; break; case 值2: 语句块2; break; … case 值n: 语句块n; break; default: 语句块n+1; break; }
其中,switch、case、default、break 都是 Java 的关键字。
switch
表示“开关”,这个开关就是 switch 关键字后面小括号里的值,小括号里要放一个整型变量或字符型变量。
表达式必须为 byte,short,int,char类型。
Java7 增强了 switch 语句的功能,允许 switch 语句的控制表达式是 java.lang.String 类型的变量或表达式。
只能是 java.lang.String 类型,不能是 StringBuffer 或 StringBuilder 这两种字符串的类型。
case
表示“情况,情形”,case 标签可以是:
- 类型为 char、byte、 short 或 int 的常量表达式。
- 枚举常量。
- 从 Java SE 7 开始, case 标签还可以是字符串字面量。
例如:
String input = ...; switch (input.toLowerCase()) { // toLowerCase用于将大写字符转换为小写 case "yes": ... break; }
当在 switch 语句中使用枚举常量时,不必在每个标签中指明枚举名,可以由 switch 的表达式值确定。例如:
Size sz = ...; switch (sz) { case SMALL: // no need to use Size.SMALL ... break; ... }
注意:重复的 case 值是不允许的。
default
表示“默认”,即其他情况都不满足。
default 后要紧跟冒号,default 块和 case 块的先后顺序可以变动,不会影响程序执行结果。
通常,default 块放在末尾,也可以省略不写。
break
表示“停止”,即跳出当前结构。
如果在 case 分支语句的末尾没有 break 语句,有可能触发多个 case 分支。
那么就会接着执行下一个 case 分支语句。这种情况相当危险,常常会引发错误。
为此,我们在程序中从不使用 switch 语句。
如果你喜欢 switch 语句,编译代码时可以考虑加上 -Xlint:fallthrough 选项,如下所示:
javac -Xlint:fallthrough Test.java
这样一来,如果某个分支最后缺少一个 break 语句,编译器就会给出一个警告消息。
switch 语句的执行过程如下:表达式的值与每个 case 语句中的常量作比较。
如果发现了一个与之相匹配的,则执行该 case 语句后的代码。
如果没有一个 case 常量与表达式的值相匹配,则执行 default 语句。
当然,default 语句是可选的。如果没有相匹配的 case 语句,也没有 default 语句,则什么也不执行。
图 1 switch语句执行流程图
例 1
在节目的抽奖环节里,节目组会根据每位嘉宾的座位号来进行抽奖游戏,根据不同的号码来决定奖项的大小。
使用 switch 语句编写 Java 程序来完成奖项分配,其实现代码如下。
public static void main(String[] args) { System.out.println("请输入座位号码:"); Scanner sc = new Scanner(System.in); int num = sc.nextInt(); switch (num) { case 8: System.out.println("恭喜你,获得了三等奖!"); break; case 88: System.out.println("恭喜你,获得了二等奖!"); break; case 888: System.out.println("恭喜你,获得了一等奖!"); break; default: System.out.println("谢谢参与!"); break; } }
当用户输入的号码为 888 时,获取的 num 值为 888,则与第三个 case 后的值匹配,执行它后面的语句,输出“恭喜你,获得了一等奖!”,然后执行 break 语句,跳出整个 switch 结构。如果输入的号码与 case 中的值都不匹配,则执行 default 后的语句。
程序执行结果如下所示:
请输入座位号码:
888
恭喜你,获得了一等奖!
请输入座位号码:
88
恭喜你,获得了二等奖!
请输入座位号码:
66
谢谢参与!
例 2
编写一个 Java 程序,根据当前的星期数字输出对应的汉字。在这里使用包含 break 的 switch 语句来判断当前的星期,实现代码如下:
public static void main(String[] args) { String weekDate = ""; Calendar calendar = Calendar.getInstance(); // 获取当前时间 int week = calendar.get(Calendar.DAY_OF_WEEK) - 1; // 获取星期的第几日 switch (week) { case 0: weekDate = "星期日"; break; case 1: weekDate = "星期一"; break; case 2: weekDate = "星期二"; break; case 3: weekDate = "星期三"; break; case 4: weekDate = "星期四"; break; case 5: weekDate = "星期五"; break; case 6: weekDate = "星期六"; break; } System.out.println("今天是 " + weekDate); }
本程序首先获取当前的星期值,然后使用 switch 语句判断 week 的值:0 表示星期日,1 表示星期一,2 表示星期二……以此类推,6 表示星期六。只要 week 值与 case 值相符合,则程序将执行该 case 中的语句,并跳出 switch 语句,输出结果。
运行程序,输出的结果如下:
今天是星期五
嵌套 switch 语句
可以将一个 switch 语句作为一个外部 switch 语句的语句序列的一部分,这称为嵌套 switch 语句。
因为一个 switch 语句定义了自己的块,外部 switch 语句和内部 switch 语句的 case 常量不会产生冲突。
例如,下面的程序段是完全正确的:
public static void main(String[] args) { switch (count) { case 1: switch (target) { case 0: System.out.println("target is zero"); break; case 1: System.out.println("target is one"); break; } break; case 2: // ... } }
本例中,内部 switch 语句中的 case 1 :语句与外部 switch 语句中的 case 1 :语句不冲突。
变量 count 仅与外层的 case 语句相比较。
如果变量 count 为 1,则变量 target 与内层的 case 语句相比较。
学到这里我们可以发现以下几点:
- switch 语句不同于 if 语句的是 switch 语句仅能测试相等的情况,而 if 语句可计算任何类型的布尔表达式。也就是 switch 语句只能寻找 case 常量间某个值与表达式的值相匹配。
- 在同一个 switch 语句中没有两个相同的 case 常量。当然,外部 switch 语句中的 case 常量可以和内部 switch 语句中的 case 常量相同。
- switch 语句通常比一系列嵌套 if 语句更有效。
最后一点尤其有趣,因为它使我们知道 Java 编译器如何工作。
当编译一个 switch 语句时,Java 编译器将检查每个 case 常量并且创造一个“跳转表”,这个表将用来在表达式值的基础上选择执行路径。
因此,如果你需要在一组值中做出选择,switch 语句将比与之等效的 if-else 语句快得多。
编译器可以这样做是因为它知道 case 常量都是同类型的,所要做的只是将它与 switch 表达式相比较看是否相等。
对于一系列的 if 表达式,编译器就无此功能。
if 语句和 switch 语句的区别
if 和 switch 语句都表示条件语句,可以从使用效率和实用性两方面加以区分。
1.从使用效率上区分
从使用效率上区分,在对同一个变量的不同值作条件判断时,既可以使用 switch 语句,也可以使用 if 语句。
使用 switch 语句的效率更高一些,尤其是判断的分支越多,越明显。
2. 从实用性上区分
从语句的实用性角度区分,switch 语句不如 if 条件语句,if 语句是应用最广泛和最实用的语句。
3. 何时使用 if 语句和 switch 语句
在程序开发的过程中,何时使用 if 语句和 switch 语句,需要根据实际情况而定,应尽量做到物尽其用。
不能因为 switch 语句的效率高就一直使用,也不能因为 if 语句常用就不用 switch 语句。
需要根据实际情况,具体问题具体分析,使用最适合的条件语句。
一般情况下,对于判断条件较少的,可以使用 if 条件语句,但是在实现一些多条件的判断中,最好使用 switch 语句。
Java while和do while循环详解
循环是程序中的重要流程结构之一。
循环语句能够使程序代码重复执行,适用于需要重复一段代码直到满足特定条件为止的情况。
所有流行的编程语言中都有循环语句。
Java 中采用的循环语句与C语言中的循环语句相似,主要有 while、do-while 和 for。
另外 Java 5 之后推出了 for-each 循环语句,for-each 循环是 for 循环的变形,它是专门为集合遍历而设计的。for-each 并不是一个关键字。
循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体。
当反复执行这个循环体时,需要在合适的时候把循环条件改为假,从而结束循环,否则循环将一直执行下去,形成死循环。
循环语句可能包含如下 4 个部分。
- 初始化语句(init statement): 一条或多条语句,这些语句用于完成一些初始化工作,初始化语句在循环开始之前执行。
- 循环条件(test_expression):这是一个 boolean 表达式,这个表达式能决定是否执行循环体。
- 循环体(body_statement):这个部分是循环的主体,如果循环条件允许,这个代码块将被重复执行。如果这个代码块只有一行语句,则这个代码块的花括号是可以省略的。
- 迭代语句(iteration_statement):这个部分在一次循环体执行结束后,对循环条件求值之前执行,通常用于控制循环条件中的变量,使得循环在合适的时候结束。
上面 4 个部分只是一般性的分类,并不是每个循环中都非常清晰地分出了这 4 个部分。
由于篇幅有限,本文主要介绍 while 和 do-while。
while 语句
while 语句是 Java 最基本的循环语句,是一种先判断的循环结构,可以在一定条件下重复执行一段代码。
该语句需要判断一个测试条件,如果该条件为真,则执行循环语句(循环语句可以是一条或多条),否则跳出循环。
while 循环语句的语法结构如下:
while(条件表达式) { 语句块; }
其中语句块中的代码可以是一条或者多条语句,而条件表达式是一个有效的 boolean 表达式,它决定了是否执行循环体。当条件表达式的值为 true 时,就执行大括号中的语句块。
执行完毕,再次检查表达式是否为 true,如果还为 true,则再次执行大括号中的代码,否则就跳出循环,执行 while 循环之后的代码。图 1 表示了 while 循环语句的执行流程。
图 1 while 循环语句执行流程图
例 1
使用 while 语句计算 10 的阶乘,其具体代码如下所示。
public static void main(String[] args) { int i = 1; int n = 1; while(i <= 10) { n=n*i; i++; } System.out.println("10的阶乘结果为:"+n); }
在上述代码中,定义了两个变量 i 和 n,循环每执行一次 i 值就加 1,判断 i 的值是否小于等于 10,并利用 n=n*i 语句来实现阶乘。当 i 的值大于 10 之后,循环便不再执行并退出循环。
运行程序,执行的结果如下所示:
10 的阶乘结果为:3628800
do-while 语句
如你刚才所见,如果 while 循环一开始条件表达式就是假的,那么循环体就根本不被执行
。然而,有时需要在开始时条件表达式即使是假的情况下,while 循环至少也要执行一次。
换句话说,有时你需要在一次循环结束后再测试中止表达式,而不是在循环开始时。
幸运的是,Java就提供了这样的循环:do-while循环。
do-while 循环语句也是 Java 中运用广泛的循环语句,它由循环条件和循环体组成,但它与 while 语句略有不同。
do-while 循环语句的特点是先执行循环体,然后判断循环条件是否成立。
do-while 语句的语法格式如下:
do { 语句块; }while(条件表达式);
以上语句的执行过程是,首先执行一次循环操作,然后再判断 while 后面的条件表达式是否为 true,如果循环条件满足,循环继续执行,否则退出循环。
while 语句后必须以分号表示循环结束,其运行流程如图 2 所示。
图 2 do-while 循环语句的执行流程
例 2
编写一个程序,计算 10 的阶乘。使用 do-while 循环的实现代码如下所示。
public static void main(String[] args) { int number = 1,result = 1; do { result*=number; number++; }while(number <= 10); System.out.print("10阶乘结果是:"+result); }
程序运行后输出结果如下:
10 阶乘结果是:3628800
例 3
在一个图书系统的推荐图书列表中保存了 50 条信息,现在需要让它每行显示 10 条,分 5 行进行显示。下面使用 do-while 循环语句来实现这个效果,其具体代码如下所示。
public static void main(String[] args) { int bookIndex = 1; do { System.out.print(bookIndex+"\t"); if(bookIndex%10 == 0) { System.out.println(); } bookIndex++; }while(bookIndex<51); }
在上述代码中, 声明一个变量 bookIndex 用来保存图书的索引,该变量赋值为 1 表示从第一本开始。
在 do-while 循环体内,首先输出了 bookIndex 的值,然后判断 bookIndex 是否能被 10 整除,如果可以则说明当前行已经输出 10 条,用 System.out.println() 语句输出了一个换行符。
之后使 bookIndex 加 1,相当于更新当前的索引。最后在 while 表达式中判断是否超出循环的范围,即 50 条以内。
运行程序,执行的结果如下所示。
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
while和do-while的比较
while 循环和 do-while 循环的相同处是:都是循环结构,使用 while(循环条件) 表示循环条件,使用大括号将循环操作括起来。
while 循环和 do-while 循环的不同处如下:
- 语法不同:与 while 循环相比,do-while 循环将 while 关键字和循环条件放在后面,而且前面多了 do 关键字,后面多了一个分号。
- 执行次序不同:while 循环先判断,再执行。do-while 循环先执行,再判断。
- 一开始循环条件就不满足的情况下,while 循环一次都不会执行,do-while 循环则不管什么情况下都至少执行一次。
Java for循环详解
for 语句是应用最广泛、功能最强的一种循环语句。
大部分情况下,for 循环可以代替 while 循环、do while 循环。
for 语句是一种在程序执行前就要先判断条件表达式是否为真的循环语句。
假如条件表达式的结果为假,那么它的循环语句根本不会执行。
for 语句通常使用在知道循环次数的循环中。
for 语句语法格式如下所示。
for(条件表达式1;条件表达式2;条件表达式3) { 语句块; }
for 关键字后面括号中的 3 个条件表达式必须用“;”隔开。
for 循环中的这 3 部分以及大括号中使循环体必需的 4 个组成部分完美地结合在一起,简单明了。
for 循环语句执行的过程为:首先执行条件表达式 1 进行初始化,然后判断条件表达式 2 的值是否为 true,如果为 true,则执行循环体语句块;否则直接退出循环。最后执行表达式 3,改变循环变量的值,至此完成一次循环。
接下来进行下一次循环,直到条件表达式 2 的值为 false,才结束循环,其运行流程如图 1 所示。
图 1 for循环执行流程图
值得指出的是,for 循环的循环迭代语句并没有与循环体放在一起,因此即使在执行循环体时遇到 continue 语句结束本次循环,循环迭代语句也一样会得到执行。
for 循环和 while、do while 循环不一样:
由于 while、do while 循环的循环迭代语句紧跟着循环体,因此如果循环体不能完全执行,如使用 continue 语句来结束本次循环,则循环迭代语句不会被执行。
但 for 循环的循环迭代语句并没有与循环体放在一起,因此不管是否使用 continue 语句来结束本次循环,循环迭代语句一样会获得执行。
与前面循环类似的是,如果循环体只有一行语句,那么循环体的大括号可以省略。
例如,同样是计算 5 的阶乘,使用 for 循环的实现代码如下:
public static void main(String[] args) { int result = 1; for (int number = 1; number <= 5; number++) { result *= number; } System.out.print("5 的阶乘结果是:" + result); // 输出"5的阶乘结果是:120" }
上述语句的含义可以理解为,将 number 变量的值从 1 开始,每次递增 1,直到大于 5 时终止循环。在循环过程中,将 number 的值与当前 result 的值进行相乘。
for 语句中初始化、循环条件以及迭代部分都可以为空语句(但分号不能省略),三者均为空的时候,相当于一个无限循环。下面对这些情况依次进行介绍。
条件表达式 1 为空
for 语句中条件表达式 1 的作用可以在程序的其他位置给出,所以当条件表达式 1 为空时,for 语句后面括号内其他条件表达式执行的顺序不变。
例如,使用 for 语句的这种形式计算 1~100 所有奇数的和。
public static void main(String[] args) { int result = 0; int number = 1; // 相当于for语句的第1个表达式 for (; number < 101; number++) { if (number % 2 != 0) // 如果不能整除2,说明是奇数,则进行累加 result += number; } System.out.print("100 以内所有奇数和为:" + result); }
执行后的输出结果如下:
100 以内所有奇数和为:2500
条件表达式 2 为空
当 for 语句中条件表达式 2 为空时,将没有循环的终止条件。
此时 for 语句会认为条件表达式 2 的值总是为真,循环无限制执行下去。因此,为了使循环达到某种条件时退出,需要在语句块中进行逻辑判断,并使用 break 语句来跳出循环,否则将产生死循环。
同样是计算 1~100 所有奇数的和,使用这种方式的代码如下。
public static void main(String[] args) { int result = 0; for (int number = 1;; number++) { if (number > 100) break; // 相当于for语句的表达式2,满足时就退出for循环 if (number % 2 != 0) // 如果不能整除2,说明是奇数,则进行累加 result += number; } System.out.print("100 以内所有奇数和为:" + result); }
条件表达式 3 为空
当 for 语言中条件表达式 3 为空时,也就没有设置控制变量的表达式,即每次循环之后无法改变变量的值,此时也无法保证循环正常结束。
同样是计算1~100 所有奇数的和,使用这种方式的代码如下:
public static void main(String[] args) { int result = 0; for (int number = 1; number < 101;) { if (number % 2 != 0) // 如果不能整除2,说明是奇数,则进行累加 result += number; number++; // 相当于for语句的条件表达式3,每次递增1 } System.out.print("100 以内所有奇数和为:" + result); }
如果没有循环体语句,number 变量的值为 1,永远小于 101,因此将无法结束循环,形成无限循环。
在上面代码中将 number 的递增语句放在 for 循环体内,效果与完整 for 语句功能相同。
3 个条件表达式都为空
在 for 循环语句中,无论缺少哪部分条件表达式,都可以在程序的其他位置补充,从而保持 for 循环语句的完整性,使循环正常进行。
当 for 语句中循环体全为空时,即没有循环初值,不判断循环条件,循环变量不增值,此时无条件执行循环体,形成无限循环或者死循环。
对于这种情况,读者在使用时应该尽量避免。
例如,计算 1~100 所有奇数的和,使用这种方式的代码如下:
public static void main(String[] args) { int result = 0; int number = 1; // 相当于for语句的条件表达式1 for (;;) { if (number > 100) break; // 相当于for语句的条件表达式2 if (number % 2 != 0) // 如果不能整除2,说明是奇数,则进行累加 result += number; number++; // 相当于for语句的条件表达式3 } System.out.print("100 以内所有奇数和为: " + result); }
例 1
编写一个 Java 程序,统计某超市上半年的总销售量,要求由用户输入每月的销量。使用 for 循环的实现代码如下。
public static void main(String[] args) { int sum = 0; int num = 0; Scanner sc = new Scanner(System.in); for (int i = 1; i <= 6; i++) { System.out.println("请输入第" + i + " 个月的销售数量:"); num = sc.nextInt(); sum += num; } System.out.println("上半年的销售总量为:" + sum); }
在该程序中, 声明循环变量 i,控制循环的次数,它被初始化为 1。
每执行一次循环,都要对 i 进行判断,看其值是否小于等于 6,条件成立则继续累加成绩,否则退出循环。
每执行完一次循环体,都会对 i 累加 1。
如此循环重复,直到 i 的值大于 6 时停止循环。此时退出 for 循环体,执行最下方的语句输出累加的销售总量。
运行程序,执行结果如下所示。
请输入第1 个月的销售数量:
6840
请输入第2 个月的销售数量:
5449
请输入第3 个月的销售数量:
6546
请输入第4 个月的销售数量:
2400
请输入第5 个月的销售数量:
908
请输入第6 个月的销售数量:
8048
上半年的销售总量为:30191
一般选择循环变量时,习惯选择 i、j、k 来作为循环变量。
for、do-while 和 while 的区别
例2
分别用 for、do-while 和 while 求出 1-10 的和。
使用for循环
代码如下:
public static void main(String[] args) { int sum = 0; for (int i = 1; i < 11; i++) { sum = sum + i; } System.out.println(sum); }
运行结果为 55。
使用 do-while 循环
代码如下:
public static void main(String[] args) { int sum = 0; int i = 1; do { sum = sum + i; i++; } while (i < 11); System.out.println(sum); }
运行结果为 55。
使用 while 循环
代码如下:
public static void main(String[] args) { int sum = 0; int i = 1; while (i < 11) { sum = sum + i; i++; } System.out.println(sum); }
运行结果为 55。
从上边代码可以看出 for 语句明显更加简练,因为知道循环次数。
到此这篇关于Java流程控制语句最全汇总(中篇)的文章就介绍到这了,其他两个部分的内容(上、下篇)请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!