Skip to content

Java 中的 switch-case 选择结构

语法格式:

java
switch(表达式){
    case 常量值1:
        语句块1;
        // break;
    case 常量值2:
        语句块2;
        // break; 
    // ...
   [default:
        语句块n+1;
        break;
   ]
}

执行过程:

  • 第 1 步:根据 switch 中表达式的值,依次匹配各个 case。如果表达式的值等于某个 case 中的常量值,则执行对应 case 中的执行语句。

  • 第 2 步:执行完此 case 的执行语句以后,

    • 情况 1:如果遇到 break,则执行 break 并跳出当前的 switch-case 结构
    • 情况 2:如果没有遇到 break,则会继续执行当前 case 之后的其它 case 中的执行语句。直到遇到 break 关键字或执行完所有的 case 及 default 的执行语句,跳出当前的 switch-case 结构(case 穿透)

使用注意点:

  • switch(表达式)中表达式的值必须是下述几种类型之一:byte,short,char,int,枚举 (jdk 5.0),String (jdk 7.0);
  • case 子句中的值必须是常量,不能是变量名或不确定的表达式值或范围;
  • 同一个 switch 语句,所有 case 子句中的常量值互不相同;
  • break 语句用来在执行完一个 case 分支后使程序跳出 switch 语句块;如果没有 break,程序会顺序执行到 switch 结尾;
  • default 子句是可选的。同时,位置也是灵活的。当没有匹配的 case 时,执行 default 语句。

应用举例

案例 1:

java
public class Case1 {
    public static void main(String args[]) {
        int num = 1;
		switch(num){
			case 0:
				System.out.println("zero");
				break;
			case 1:
				System.out.println("one");
				break;
			case 2:
				System.out.println("two");
				break;
			case 3:
				System.out.println("three");
				break;
			default:
				System.out.println("other");
				//break;
		}
    }
}

案例 2:

java
public class Case2 {
    public static void main(String args[]) {
        String season = "summer";
        switch (season) {
            case "spring":
                System.out.println("春暖花开");
                break;
            case "summer":
                System.out.println("夏日炎炎");
                break;
            case "autumn":
                System.out.println("秋高气爽");
                break;
            case "winter":
                System.out.println("冬雪皑皑");
                break;
            default:
                System.out.println("季节输入有误");
                break;
        }
    }
}

错误举例:

java
int key = 10;
switch(key){
	case key > 0 :
        System.out.println("正数");
        break;
    case key < 0:
        System.out.println("负数");
        break;
    default:
        System.out.println("零");
        break;
}

案例 3:

使用 switch-case 实现:对学生成绩大于 60 分的,输出“合格”。低于 60 分的,输出“不合格”。

java
class Case3 {
	public static void main(String[] args) {
		
		int score = 67;
		/*
		写法 1:极不推荐
		switch(score){
			case 0:
				System.out.println("不及格");
				break;
			case 1:
				System.out.println("不及格");
				break;
			//...

			case 60:
				System.out.println("及格");
				break;
			//...略...
		
		}
		*/

		//写法 2:
		switch(score / 10){
			case 0:
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
				System.out.println("不及格");
				break;
			case 6:
			case 7:
			case 8:
			case 9:
			case 10:
				System.out.println("及格");
				break;
			default:
				System.out.println("输入的成绩有误");
				break;
		}

		//写法 3:
		switch(score / 60){
			case 0:
				System.out.println("不及格");
				break;
			case 1:
				System.out.println("及格");
				break;
			default:
				System.out.println("输入的成绩有误");
				break;
		}
	}
}

利用 case 的穿透性

在 switch 语句中,如果 case 的后面不写 break,将出现穿透现象,也就是一旦匹配成功,不会在判断下一个 case 的值,直接向后运行,直到遇到 break 或者整个 switch 语句结束,执行终止。

案例 4:

编写程序:从键盘上输入 2023 年的“month”和“day”,要求通过程序输出输入的日期为 2023 年的第几天。

java
import java.util.Scanner;

class Case4 {
	public static void main(String[] args) {
		
		Scanner scan = new Scanner(System.in);

		System.out.println("请输入 2023 年的 month:");
		int month = scan.nextInt();

		System.out.println("请输入 2023 年的 day:");
		int day = scan.nextInt();

		//这里就不针对 month 和 day 进行合法性的判断了,以后可以使用正则表达式进行校验。

		int sumDays = 0; // 记录总天数
		
		// 写法 1:不推荐(存在冗余的数据)
		/*
		switch(month){
			case 1:
				sumDays = day;
				break;
			case 2:
				sumDays = 31 + day;
				break;
			case 3:
				sumDays = 31 + 28 + day;
				break;
			//....
		
			case 12:
				//sumDays = 31 + 28 + ... + 30 + day;
				break;
		}
		*/

		// 写法 2:推荐
		switch(month){
			case 12:
				sumDays += 30;// 这个 30 是代表 11 月份的满月天数
			case 11:
				sumDays += 31; // 这个 31 是代表 10 月份的满月天数
			case 10:
				sumDays += 30; // 这个 30 是代表 9 月份的满月天数
			case 9:
				sumDays += 31; // 这个 31 是代表 8 月份的满月天数
			case 8:
				sumDays += 31; // 这个 31 是代表 7 月份的满月天数
			case 7:
				sumDays += 30; // 这个 30 是代表 6 月份的满月天数
			case 6:
				sumDays += 31; // 这个 31 是代表 5 月份的满月天数
			case 5:
				sumDays += 30; // 这个 30 是代表 4 月份的满月天数
			case 4:
				sumDays += 31; // 这个 31 是代表 3 月份的满月天数
			case 3:
				sumDays += 28; // 这个 28 是代表 2 月份的满月天数
			case 2:
				sumDays += 31; // 这个 31 是代表 1 月份的满月天数
			case 1:
				sumDays += day; // 这个 da y 是代 表 当月的第几天
		}
		
		System.out.println(month + " 月 " + day + " 日是 2023 年的第 " + sumDays + " 天");
        //关闭资源
		scan.close();
	}
}

拓展:判断年第几天

从键盘分别输入年、月、日,判断这一天是当年的第几天。

注:判断一年是否是闰年的标准:1)可以被 4 整除,但不可被 100 整除或 2)可以被 400 整除。

例如:1900,2200 等能被 4 整除,但同时能被 100 整除,但不能被 400 整除,不是闰年。

java
import java.util.Scanner;

public class JudgeYearDay {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入 year:");
        int year = scanner.nextInt();

        System.out.print("请输入 month:");
        int month = scanner.nextInt();

        System.out.print("请输入 day:");
        int day = scanner.nextInt();

        // 判断这一天是当年的第几天 ==> 从 1 月 1 日开始,累加到 xx 月 xx 日这一天
        // (1) [1, month-1] 个月满月天数
        // (2) 单独考虑 2 月份是否是 29 天(依据是看 year 是否是闰年)
        // (3) 第 month 个月的 day 天

        // 声明一个变量 days,用来存储总天数
        int sumDays = 0;

        // 累加 [1,month-1] 个月满月天数
        switch (month) {
            case 12:
                // 累加的 1-11 月
                sumDays += 30; // 这个 30 是代表 11 月份的满月天数
                // 这里没有 break,继续往下走
            case 11:
                // 累加的 1-10 月
                sumDays += 31; // 这个 31 是代表 10 月的满月天数
                // 这里没有 break,继续往下走
            case 10:
                sumDays += 30; // 9 月
            case 9:
                sumDays += 31; // 8 月
            case 8:
                sumDays += 31; // 7 月
            case 7:
                sumDays += 30; // 6 月
            case 6:
                sumDays += 31; // 5 月
            case 5:
                sumDays += 30; // 4 月
            case 4:
                sumDays += 31; // 3 月
            case 3:
                sumDays += 28; // 2 月,正常为 28 天,遇到闺年为 29 天
                // 在这里考虑是否可能是 29 天
                if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                    sumDays++; // 多加 1 天
                }
            case 2:
                sumDays += 31; // 1 月
            case 1:
                sumDays += day; // 第 month 月的 day 天
        }

        // 输出结果
        System.out.println(year + " 年 " + month + " 月 " + day + " 日是这一年的第 " + sumDays + " 天");

        scanner.close();
    }
}

使用:

$ java JudgeYearDay
请输入year:2023
请输入month:10
请输入day:19
2023 年 10 月 19 日是这一年的第 292 天

案例 5:根据指定的月份输出对应季节

java
// 根据指定的月份输出对应季节

import java.util.Scanner;

/*
 * 需求:指定一个月份,输出该月份对应的季节。一年有四季:
 * 		3, 4, 5	春季
 * 		6, 7, 8	夏季
 * 		9, 10, 11	秋季
 * 		12, 1, 2	冬季
 */
public class Case5 {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("请输入月份:");
        int month = input.nextInt();

        /*
		switch(month) {
            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;
            case 7:
                System.out.println("夏季");
                break;
            case 8:
                System.out.println("夏季");
                break;
            case 9:
                System.out.println("秋季");
                break;
            case 10:
                System.out.println("秋季");
                break;
            case 11:
                System.out.println("秋季");
                break;
            case 12:
                System.out.println("冬季");
                break;
            default:
                System.out.println("你输入的月份有误");
                break;
		}
		*/

        // 改进版
        switch(month) {
            case 1:
            case 2:
            case 12:
                System.out.println("冬季");
                break;
            case 3:
            case 4:
            case 5:
                System.out.println("春季");
                break;
            case 6:
            case 7:
            case 8:
                System.out.println("夏季");
                break;
            case 9:
            case 10:
            case 11:
                System.out.println("秋季");
                break;
            default:
                System.out.println("你输入的月份有误");
                break;
        }

        input.close();
    }
}

使用 if-else 实现:

java
if ((month == 1) || (month == 2) || (month == 12)) {
    System.out.println("冬季");
} else if ((month == 3) || (month == 4) || (month == 5)) {
    System.out.println("春季");
} else if ((month == 6) || (month == 7) || (month == 8)) {
    System.out.println("夏季");
} else if ((month == 9) || (month == 10) || (month == 11)) {
    System.out.println("秋季");
} else {
    System.out.println("你输入的月份有误");
}

比较 if-else 语句与 switch-case 语句

  • 结论:凡是使用 switch-case 的结构都可以转换为 if-else 结构。反之,不成立。
  • 开发经验:如果既可以使用 switch-case,又可以使用 if-else,建议使用 switch-case。因为效率稍高。
  • 细节对比:
    • if-else 语句优势
      • if 语句的条件是一个布尔类型值,if 条件表达式为 true 则进入分支,可以用于范围的判断,也可以用于等值的判断,使用范围更广
      • switch 语句的条件是一个常量值(byte、short、int、char、枚举、String),只能判断某个变量或表达式的结果是否等于某个常量值,使用场景较狭窄
    • switch 语句优势
      • 当条件是判断某个变量或表达式是否等于某个固定的常量值时,使用 if 和 switch 都可以,习惯上使用 switch 更多。因为效率稍高。当条件是区间范围的判断时,只能使用 if 语句。
      • 使用 switch 可以利用穿透性,同时执行多个分支,而 if...else 没有穿透性。

案例:只能使用 if-else

从键盘输入一个整数,判断是正数、负数、还是零。

java
import java.util.Scanner;

public class OnlyIfElse {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        System.out.print("请输入整数:");
        int num = input.nextInt();

        if (num > 0) {
            System.out.println(num + "是正整数");
        } else if (num < 0) {
            System.out.println(num + "是负整数");
        } else {
            System.out.println(num + "是零");
        }

        input.close();
    }
}

练习

练习 1:星期英文单词

从键盘输入星期的整数值,输出星期的英文单词。

java
import java.util.Scanner;

public class Exer1 {
    public static void main(String[] args) {
        // 定义指定的星期
        Scanner input = new Scanner(System.in);
        System.out.print("请输入星期值:");
        int weekday = input.nextInt();

        // switch 语句实现选择
        switch(weekday) {
            case 1:
                System.out.println("Monday");
                break;
            case 2:
                System.out.println("Tuesday");
                break;
            case 3:
                System.out.println("Wednesday");
                break;
            case 4:
                System.out.println("Thursday");
                break;
            case 5:
                System.out.println("Friday");
                break;
            case 6:
                System.out.println("Saturday");
                break;
            case 7:
                System.out.println("Sunday");
                break;
            default:
                System.out.println("你输入的星期值有误!");
                break;
        }

        input.close();
    }
}

练习 2:转大小写

使用 switch 把小写类型的 char 型转为大写。只转换 a,b,c,d,e。其它的输出“other”。

java
public class Exer2 {

    public static void main(String[] args) {

        char word = 'c';
        switch (word) {
            case 'a':
                System.out.println("A");
                break;
            case 'b':
                System.out.println("B");
                break;
            case 'c':
                System.out.println("C");
                break;
            case 'd':
                System.out.println("D");
                break;
            case 'e':
                System.out.println("E");
                break;
            default :
                System.out.println("other");
        }
    }
}

练习 3:成绩等级

编写程序:从键盘上读入一个学生成绩,存放在变量 score 中,根据 score 的值输出其对应的成绩等级:

score >= 90           等级:  A
70 <= score < 90        等级:  B    
60 <= score < 70        等级:  C
score < 60            等级:  D

方式一:使用 if-else
方式二:使用 switch-case: score / 10: 0 - 10
java
import java.util.Scanner;

public class Exer3 {

    public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);
        System.out.println("请输入学生成绩:");
        int score = scan.nextInt();

        char grade;//记录学生等级
        //方式 1:
//        if(score >= 90){
//            grade = 'A';
//        }else if(score >= 70 && score < 90){
//            grade = 'B';
//        }else if(score >= 60 && score < 70){
//            grade = 'C';
//        }else{
//            grade = 'D';
//        }

        //方式 2:
        switch(score / 10){
            case 10:
            case 9:
                grade = 'A';
                break;
            case 8:
            case 7:
                grade = 'B';
                break;
            case 6:
                grade = 'C';
                break;
            default :
                grade = 'D';
        }

        System.out.println("学生成绩为" + score + ",对应的等级为" + grade);

        scan.close();
    }
}

练习 4:计算生肖

编写一个程序,为一个给定的年份找出其对应的中国生肖。中国的生肖基于 12 年一个周期,每年用一个动物代表:rat、ox、tiger、rabbit、dragon、snake、horse、sheep、monkey、rooster、dog、pig。

提示:2022 年:虎。2022 % 12 == 6
java
import java.util.Scanner;

public class Exer4 {
    public static void main(String[] args){
        //从键盘输入一个年份
        Scanner input = new Scanner(System.in);
        System.out.print("请输入年份:");
        int year = input.nextInt();
        input.close();

        //判断
        switch(year % 12){
            case 0:
                System.out.println(year + "是猴年");
                break;
            case 1:
                System.out.println(year + "是鸡年");
                break;
            case 2:
                System.out.println(year + "是狗年");
                break;
            case 3:
                System.out.println(year + "是猪年");
                break;
            case 4:
                System.out.println(year + "是鼠年");
                break;
            case 5:
                System.out.println(year + "是牛年");
                break;
            case 6:
                System.out.println(year + "是虎年");
                break;
            case 7:
                System.out.println(year + "是兔年");
                break;
            case 8:
                System.out.println(year + "是龙年");
                break;
            case 9:
                System.out.println(year + "是蛇年");
                break;
            case 10:
                System.out.println(year + "是马年");
                break;
            case 11:
                System.out.println(year + "是羊年");
                break;
            default:
                System.out.println(year + "输入错误");
        }
    }
}

练习 5:押宝游戏

随机产生 3 个 1-6 的整数,如果三个数相等,那么称为“豹子”,如果三个数之和大于 9,称为“大”,如果三个数之和小于等于 9,称为“小”,用户从键盘输入押的是“豹子”、“大”、“小”,并判断是否猜对了。

提示:随机数 Math.random() 产生 [0,1) 范围内的小数。
     如何获取 [a,b] 范围内的随机整数呢?(int)(Math.random() * (b - a + 1)) + a

练习 6

使用 switch 语句改写下列 if 语句:

java
int a = 3;
int x = 100;
if(a==1)
	x+=5;
else if(a==2)
	x+=10;
else if(a==3)
	x+=16;
else
	x+=34;

改写:

java
int a = 3;
int x = 100;

switch(a){
    case 1:
        x += 5;
        break;
    case 2:
        x += 10;
        break;
    case 3:
        x += 16;
        break;
    default :
        x += 34;

}

Released under the MIT License.