四、流程控制--if else和switch(阶段二)
一、if else语句
if 结构
if 语句是使用最多的条件分支结构,它属于选择语句,也可以称为条件语句。
if 选择结构是根据条件判断之后再做处理的一种语法结构。默认情况下,if 语句控制着下方紧跟的一条语句的执行。不过,通过语句块,if 语句可以控制多个语句。
if 语句的最简语法格式如下,表示“如果满足某种条件,就进行某种处理”。
if (条件表达式) {
语句块;
}
其中“条件表达式”和“语句块”是比较重要的两个地方。
-
条件表达式
:条件表达式可以是任意一种逻辑表达式,最后返回的结果必须是一个布尔值。取值可以是一个单纯的布尔变量或常量,也可以是使用关系或布尔运算符的表达式。如果条件为真,那么执行语句块;如果条件为假,则语句块将被绕过而不被执行。 -
语句块
:该语句块可以是一条语句也可以是多条语句。如果仅有一条语句,可省略条件语句中的大括号 {}。当从编程规范角度不要省略大括号,省略大括号会使程序的可读性变差。
if 条件语句的运行流程如图 1 所示。
图1 if 语句执行流程图
例 1
编写一个 Java 程序,允许用户从键盘输入一个数字,再判断该数是否大于 100。使用 if 语句的实现代码如下:
public static void main(String[] args) {
System.out.println("请输入一个数字:");
Scanner input = new Scanner(System.in);
int num = input.nextInt(); // 接收键盘输入数据
// 判断用户输入的数据是否大于100
if (num > 100) {
System.out.println("输入的数字大于100");
}
// 判断用户输入的数据是否等于100
if (num == 100) {
System.out.println("输入的数字等于100");
}
// 判断用户输入的数据是否小于100
if (num < 100) {
System.out.println("输入的数字小于100");
}
}
运行该程序,分别使用键盘输入 99、100 和 105,结果如下所示:
请输入一个数字:
99
输入的数字小于100
请输入一个数字:
100
输入的数字等于100
请输入一个数字:
105
输入的数字大于100
if-else 结构
单 if 语句仅能在满足条件时使用,而无法执行任何其他操作(停止)。而结合 else 语句的 if 可以定义两个操作,此时的 if…else 语句表示“如果条件正确则执行一个操作,否则执行另一个操作”。
使用 if…else 语句的语法格式如下所示:
if (表达式) {
语句块1;
} else {
语句块2;
}
在上述语法格式中,如果 if 关键字后面的表达式成立,那么就执行语句块 1,否则的话则执行语句块 2,其运行流程如图 2 所示。
例 子
在例 3 中为实现比较 num1 和 num2 的大小,使用了 3 个 if 条件语句分别判断大于、等于和小于的情况。下面使用 if…else 双条件来实现,具体代码如下:
public static void main(String[] args) {
int num1 = 50;
int num2 = 34;
// 如果num1等于num2
if (num1 == num2) {
System.out.println("num1等于num2");
}
// 如果num1大于num2
if (num1 > num2) {
System.out.println("num1大于num2");
} else {
// 否则就是num1小于num2
System.out.println("num1小于num2");
}
}
双条件语句减少了代码的编写量,同时增强了程序的可读性。简化后的结果还是一样,执行后会输出“num1 大于 num2”。
多条件 if-else-if 语句
if 语句的主要功能是给程序提供一个分支。然而,有时候程序中仅仅多一个分支是远远不够的,甚至有时候程序的分支会很复杂,这就需要使用多分支的 if…else if 语句。
通常表现为“如果满足某种条件,就进行某种处理,否则如果满足另一种条件才执行另一种处理……,这些条件都不满足则执行最后一种条件”。
if…else if 多分支语句的语法格式如下所示:
if(表达式1) {
语句块1;
} else if(表达式2) {
语句块2;
...
} else if(表达式n) {
语句块n;
} else {
语句块n+1;
}
可以看出,else-if 结构实际上是 if-else 结构的多层嵌套。明显的特点就是在多个分支中只执行一个语句组,而其他分支都不执行,所以这种结构可以用于有多种判断结果的分支中。
在使用 if…else if 语句时,依次判断表达式的值,当某个分支的条件表达式的值为 true 时,则执行该分支对应的语句块,然后跳到整个 if 语句之外继续执行程序。如果所有的表达式均为 false,则执行语句块 n+1,然后继续执行后续程序,其运行流程如图 3 所示。
例 子
同样以比较 num1 和 num2 的大小为例,使用 if…else if 多条件的实现代码如下:
public static void main(String[] args) {
int num1 = 50;
int num2 = 34;
if (num1 == num2) { // 如果num1等于num2
System.out.println("num1等于num2");
} else if (num1 > num2) { // 如果num1大于num2
System.out.println("num1大于num2");
} else { // 否则就是小于
System.out.println("num1小于num2");
}
}
如上述代码所示,num1 和 num2 不满足 if 语句的“num1==num2”条件,接着测试 else if 的“num1>num2”条件,满足该条件并输出“num1 大于 num2”。
嵌套 if 的使用
if 语句的用法非常灵活,不仅可以单独使用,还可以在 if 语句里嵌套另一个 if 语句。同样,if…else 语句和 if…else if 语句中也可以嵌套另一个 if 结构的语句,以完成更深层次的判断。
嵌套 if 的语法格式如下:
if(表达式1) {
if(表达式2) {
语句块1;
} else {
语句块2;
}
} else {
if(表达式3) {
语句块3;
} else if(表达式4) {
语句块4;
} else {
if(表达式n) {
语句块n;
} else {
语句块n+1;
}
}
}
在上述格式中,应该注意每一条 else 与离它最近且没有其他 else 对应的 if 相搭配,其执行流程如图 4 所示。
例 子
活动计划安排,如果今天是工作日,去上班;如果今天是周末,则出去游玩;同时,如果周末天气晴朗,去室外游乐场游玩,否则去室内游乐场游玩。实现代码如下:
public static void main(String[] args) {
String today = "周末";
String weather = "晴朗";
if (today.equals("周末")) {
if (weather.equals("晴朗")) {
System.out.println("去室外游乐场游玩");
} else {
System.out.println("去室内游乐场游玩");
}
} else {
System.out.println("去上班");
}
}
如上述代码所示,today 满足 if 语句的“today.equals(“周末”)”条件,接着测试 weather 是否满足“weather.equals(“晴朗”)”条件,满足该条件输出“去室外游乐场游玩”。
二、switch语句
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 的关键字。
1)switch
表示“开关”,这个开关就是 switch 关键字后面小括号里的值,小括号里要放一个整型变量或字符型变量。表达式必须为 byte,short,int,char类型。
Java7 增强了 switch 语句的功能,允许 switch 语句的控制表达式是 java.lang.String 类型的变量或表达式。只能是 java.lang.String 类型,不能是 StringBuffer 或 StringBuilder 这两种字符串的类型。
2)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 值是不允许的。
3)default
表示“默认”,即其他情况都不满足。default 后要紧跟冒号,default 块和 case 块的先后顺序可以变动,不会影响程序执行结果。通常,default 块放在末尾,也可以省略不写。
4)break
表示“停止”,即跳出当前结构。
如果在 case 分支语句的末尾没有 break 语句,有可能触发多个 case 分支。那么就会接着执行下一个 case 分支语句。这种情况相当危险,常常会引发错误。为此,我们在程序中从不使用 switch 语句。
如果你喜欢 switch 语句,编译代码时可以考虑加上 -Xlint:fallthrough 选项,如下所示:
javac -Xlint:fallthrough Test.java
这样一来,如果某个分支最后缺少一个 break 语句,编译器就会给出一个警告消息。
switch 语句的执行过程如下:表达式的值与每个 case 语句中的常量作比较。如果发现了一个与之相匹配的,则执行该 case 语句后的代码。如果没有一个 case 常量与表达式的值相匹配,则执行 default 语句。当然,default 语句是可选的。如果没有相匹配的 case 语句,也没有 default 语句,则什么也不执行。
例 子
在节目的抽奖环节里,节目组会根据每位嘉宾的座位号来进行抽奖游戏,根据不同的号码来决定奖项的大小。使用 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 谢谢参与!
嵌套 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 语句。