目录
一、switch的三种用法
通过前两天的学习,我们知道了if条件语句,但其实在分支结构中,除了使用if-else if-else之外,当分支量过大时,我们还可以使用switch语句,下面介绍switch的三种用法。
1.switch标准方式
1.1语法
switch (表达式) {
case 值1:
语句块1;
break;
case 值2:
语句块2;
break;
...
case 值N:
语句块N;
break;
default:
语句块N+1;
}
java中的switch标准方式与C、C++中并没有太大差异,都是首先计算表达式的值,然后将该值与每个case的值进行比较:
(1)如果找到匹配的case值,则执行该case下的语句块,直到遇到break或者到达switch语句的结尾;
(2)如果没有找到相匹配的case值,且存在default子句,则执行default子句下的语句块;
(3)如果没有找到相匹配的case值,且不存在default子句,则不执行任何操作;
switch标准方式可以多条件合并,语法如下:
switch (表达式) {
case 值1:
case 值2:
case 值3:
语句块;
break;
...
default:
语句块;
}
1.2case穿透现象(直通行为)
在switch标准方式中,如果某一个case语句中没有break关键字,那么程序就会无条件继续执行下一个case语句(即不与下一个case值进行比较就直接执行其语句块),直到遇到break或者到达switch语句的结尾,这就是case的穿透现象。
例如:
int dayOfWeek;
dayOfWeek = 2;
switch (dayOfWeek) {
case 1:
System.out.println("星期一");
case 2:
System.out.println("星期二");
case 3:
System.out.println("星期三");
case 4:
System.out.println("星期四");
case 5:
System.out.println("星期五");
case 6:
System.out.println("星期六");
default:
System.out.println("星期日");
} // of switch
输出结果为:
在上述代码中,表达式dayOfWeek的值为2,与第二个case语句匹配成功,执行其下的语句块,但由于第二个case语句中没有break关键字,所以程序就会无条件继续执行,直到到达此switch语句的结尾。
1.3注意事项
(1)在switch(表达式)中,表达式支持的数据类型:
JDK1.0~1.4可接受的数据类型有 byte、short、int、char
JDK1.5可接受的数据类型有 byte、short、int、char、enum(枚举型)、包装类型
JDK1.7可接受的数据类型有 byte、short、int、char、enum(枚举型)、包装类型、String
因为byte、short、char类型可以在不损失精度的情况下向上转换为int型;而枚举型有一个oridinal方法,该方法实际上也是一个int类型的数值;String类型有一个hashCode算法,其结果也是int型。所以总的来说,在大体上可以认为switch语句只支持int型,而long、float、double都不能用于switch语句。
(2)default可以编写在switch语句中的任意位置,因为不管把default放在哪个位置,执行switch语句时都会首先找第一个case进行匹配,只有当所有case均不匹配时,才会执行default语句,但是建议将default放在所有case的后面。
(3)所有case后面的值都必须和switch后面的表达式类型一致。
(4)break关键字用于防止case穿透现象。
2.switch - > 用法
从上文可以看出switch标准形式中会存在太多的break,从而造成代码冗余,降低程序可读性。针对此问题,可以借助函数式接口和lambda表达式简化代码,语法如下:
switch (表达式) {
case 值1 -> 语句块1;
case 值2 -> 语句块2;
......
case 值N -> 语句块N;
default -> 语句块N+1;
}
switch -> 用法其实相当于用箭头 - >取代了冒号:和break,是一种更为简单的方法,它不需要break就可以跳出判断,保证只有一条分支会被执行,避免了switch标准方式的case穿透现象。
//注意在同一个switch语句中,不能混合使用冒号:和箭头 - >。
例如:
int dayOfWeek;
dayOfWeek = 2;
switch (dayOfWeek) {
case 1 -> System.out.println("星期一");
case 2 -> System.out.println("星期二");
case 3 -> System.out.println("星期三");
case 4 -> System.out.println("星期四");
case 5 -> System.out.println("星期五");
case 6 -> System.out.println("星期六");
default -> System.out.println("星期日");
} // of switch
输出结果为:
同样的,switch - > 用法也可以实现多条件合并,语法如下:
switch (表达式) {
case 值1,值2,值3 -> 语句块;
...
default -> 语句块;
}
例如:
int dayOfWeek;
dayOfWeek = 2;
switch (dayOfWeek) {
case 1,2,3,4,5 -> System.out.println("工作日");
default -> System.out.println("其他");
} // of switch
输出结果为:
3.switch yield用法
switch标准方式和switch - > 用法都是把switch作为普通语句来使用,但实际上switch还可以作为表达式来使用,也就是说,switch是可以有返回值的,而switch yield用法就可以实现返回值。
例如:
int dayOfWeek;
dayOfWeek = 2;
String weekday = switch (dayOfWeek) {
case 1:
yield "星期一";
case 2:
yield "星期二";
case 3:
yield "星期三";
case 4:
yield "星期四";
case 5:
yield "星期五";
case 6:
yield "星期六";
default:
yield "星期日";
}; //此处要有分号
System.out.println(weekday);
输出结果为:
//与break类似,yield也起到跳出判断、终止执行的作用,但与break不同的是,yield会生成一个值,这个值就是switch表达式的返回值。
//因为把yield语句产生的值看成switch表达式的返回值,所以yield只能用在switch表达式中。
//当switch作为表达式使用时,需要在switch结构后加上分号,即switch结构中的右边大括号后加上分号。
//当switch作为表达式使用时,每个分支都必须有返回值。
二、if语句与switch语句的比较
if语句和switch语句都是java中常见的条件语句,它们都可以用于实现多重选择与判断,但二者存在一些差别,下面进行二者的比较。
1.判断方式
if语句:根据关系表达式的真假,来判断执行哪个语句块。
if(关系表达式) {
语句块1;
} else {
语句块2;
}
switch语句:根据表达式与case值的匹配情况,来判断执行哪个case下的语句块。
switch (表达式) {
case 值1:
语句块1;
break;
case 值2:
语句块2;
break;
...
case 值N:
语句块N;
break;
default:
语句块N+1;
}
2.判断流程
if语句:从上到下依次进行判断,直到找到满足条件的分支,执行该分支,执行完毕跳出if语句。
if(关系表达式1) {
语句体1;
} else if(关系表达式2) {
语句体2;
}
……
} else if(关系表达式n) {
语句体n;
}
else {
语句体n+1;
}
switch语句:找到与表达式匹配的case值,执行该分支,直到遇到break或者到达switch语句的结尾。
switch (表达式) {
case 值1:
语句块1;
break;
case 值2:
语句块2;
break;
...
case 值N:
语句块N;
break;
default:
语句块N+1;
}
3.适用情况
if((paraYear % 4 == 0) && (paraYear % 100 != 0) || (paraYear % 400 == 0)) {
return true;
} else {
return false;
} // of if
int dayOfWeek;
dayOfWeek = 2;
switch (dayOfWeek) {
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
case 3:
System.out.println("星期三");
break;
case 4:
System.out.println("星期四");
break;
case 5:
System.out.println("星期五");
break;
case 6:
System.out.println("星期六");
break;
default:
System.out.println("星期日");
} // of switch
从以上两个例子可以看出,if语句可以使用逻辑运算符(&&、||、!)对多个条件同时进行判断,而switch语句更偏向于判断离散的条件,即一个个分散的数据;if语句可以处理取等判断、区间判断,但switch语句只能用于取等判断。
三、SwitchStatement.java
根据分数评定等级是switch语句应用的一个经典案例,这个案例本质上就是单个变量在多个区间内进行判断的问题,且满足switch语句要求的条件离散性,因此能够很好的体现switch语句的特点,下面我们对该案例进行书写。
首先,针对百分值的分数,我们需要先进行如下的除10操作。
// Divide by 10, the result ranges from 0 to 10
int tempDigitalLevel = paraScore / 10;
这是因为直接对百分值分数进行分段,会造成某个分数段区间内所评定的等级是同一个,例如90~100评级为A,80~89评级为B,但是前面提到过,switch语句只能进行取等判断,无法进行区间判断,所以如果直接采用百分值分数,就无法利用switch语句进行判断。
所以我们先进行除10操作,将百分值分数除以10之后,每一个分数段区间内是同一个数值,不同的分数段区间之间是不同的数值,这就满足了switch语句对条件离散化的要求。
原百分值分数 | 除10操作后 | 对应的等级 |
100 | 10 | A |
90~99 | 9 | A |
80~89 | 8 | B |
70~79 | 7 | C |
60~69 | 6 | D |
50~59 | 5 | F |
40~49 | 4 | |
30~39 | 3 | |
20~29 | 2 | |
10~19 | 1 | |
0~9 | 0 |
其次,定义分数评级的方法(函数),如下:
public static char scoreToLevel(int paraScore) {
// E stands for error, and F stands for fail.
char resultLevel = 'E';
// Divide by 10, the result ranges from 0 to 10
int tempDigitalLevel = paraScore / 10;
// The use of break is important.
switch (tempDigitalLevel) {
case 10:
case 9:
resultLevel = 'A';
break;
case 8:
resultLevel = 'B';
break;
case 7:
resultLevel = 'C';
break;
case 6:
resultLevel = 'D';
break;
case 5:
case 4:
case 3:
case 2:
case 1:
case 0:
resultLevel = 'F';
break;
default:
resultLevel = 'E';
}// Of switch
return resultLevel;
}// of scoreToLevel
最后,进行一些数据测试,如下:
/**
*********************
* Method unit test.
*********************
*/
public static void scoreToLevelTest() {
int tempScore = 100;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 91;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 82;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 75;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 66;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 52;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 8;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 120;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
}// Of scoreToLevelTest
完整的程序代码:
package basic;
/**
* This is the fifth code. Names and comments should follow my style strictly.
*
* @author Xin Lin 310154094@qq.com.
*/
public class SwitchStatement {
/**
*********************
* The entrance of the program.
*
* @param args Not used now.
*********************
*/
public static void main(String args[]) {
scoreToLevelTest();
}// Of main
/**
*********************
* Score to level.
*
* @param paraScore From 0 to 100.
* @return The level from A to F.
*********************
*/
public static char scoreToLevel(int paraScore) {
// E stands for error, and F stands for fail.
char resultLevel = 'E';
// Divide by 10, the result ranges from 0 to 10
int tempDigitalLevel = paraScore / 10;
// The use of break is important.
switch (tempDigitalLevel) {
case 10:
case 9:
resultLevel = 'A';
break;
case 8:
resultLevel = 'B';
break;
case 7:
resultLevel = 'C';
break;
case 6:
resultLevel = 'D';
break;
case 5:
case 4:
case 3:
case 2:
case 1:
case 0:
resultLevel = 'F';
break;
default:
resultLevel = 'E';
}// Of switch
return resultLevel;
}// of scoreToLevel
/**
*********************
* Method unit test.
*********************
*/
public static void scoreToLevelTest() {
int tempScore = 100;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 91;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 82;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 75;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 66;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 52;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 8;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 120;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
}// Of scoreToLevelTest
}// Of class SwitchStatement
运行结果:
总结
1.if语句适用于对条件进行灵活的判断和处理,可以处理复杂的逻辑条件,也可以同时处理多个条件;可以处理取等判断,也可以处理区间判断。
2.switch语句适用于处理大量的离散条件,特别是单一变量的不同取值问题;只能处理取等判断。
3.选择使用if语句还是switch语句,需要根据实际情况具体分析。