日撸Java三百行(day05:基本switch语句)

目录

一、switch的三种用法

1.switch标准方式

1.1语法

1.2case穿透现象(直通行为)

1.3注意事项

2.switch - > 用法

3.switch yield用法

二、if语句与switch语句的比较

1.判断方式

2.判断流程

3.适用情况

三、SwitchStatement.java

 总结


一、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操作后对应的等级
10010A
90~999A
80~898B
70~797C
60~696D
50~595F
40~494
30~393
20~292
10~191
0~90

其次,定义分数评级的方法(函数),如下:

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语句,需要根据实际情况具体分析。

  • 29
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值