ToB企服应用市场:ToB评测及商务社交产业平台

标题: 入门篇-其之九-流程控制之条件判断 [打印本页]

作者: 八卦阵    时间: 2024-1-8 01:58
标题: 入门篇-其之九-流程控制之条件判断
本文中使用到的工具是Intellij IDEA和JDK 8,需要安装两款工具的请查看这两篇教程:点我查看安装JDK8/11/17教程点我查看安装Intellij IDEA教程
前面我们写过的代码,都是在main方法中自上到下按顺序执行的,举一个代码栗子:
  1. /**
  2. * 计算西瓜的价格
  3. *
  4. * @author iCode504
  5. * @date 2023-10-31
  6. */
  7. public class MyWatermelonDemo1 {
  8.     public static void main(String[] args) {
  9.         int price = 2;      // 西瓜的单价
  10.         int weight = 10;    // 西瓜的重量(公斤)
  11.         int totalPrice = price * weight;    // 购买价格
  12.         System.out.println("西瓜的价格是: " + totalPrice + "元");
  13.     }
  14. }
复制代码
这段代码就是先定义西瓜的单价、再定义西瓜的重量,然后计算西瓜的价格,最后对价格进行输出。像这样代码从上到下执行的结构就是顺序结构
程序一共有三种控制结构:顺序结构、选择结构和循环结构。其中选择结构是根据条件判定的结果,选择执行不同的代码,例如:红灯停,绿灯行。判断条件就是交通信号灯的状态。
Java也有选择结构,并且有多种类型的条件判断语句:单分支的if语句、双分支的if-else语句、多分支的if-else if-else语句、if嵌套语句和switch语句。
一、单分支if语句

单分支if语句的语法如下:
  1. if (条件表达式) {
  2.     执行代码...
  3. }
复制代码
其中条件表达式的计算结果必须是boolean类型。如果条件表达式的计算结果是true,那么就会执行if内部的代码;如果表达式为false,此时就会跳过if代码块(也就是if内部代码不执行),概念图如下:

我们可以在if代码块中可以编写多个执行语句。
以下是if的使用案例:
案例:之前长春下了大暴雪,气温骤降,我想在某宝上买几双棉袜子,假设每双袜子4元,请确保输入的数字大于0再计算购买价格。
分析:解题的关键在于要保证输入的数字要大于0,因此要判断输入的数字是否大于0,示例代码如下:
  1. import java.util.Scanner;
  2. /**
  3. * if条件判断
  4. *
  5. * @author iCode504
  6. * @date 2023-11-07
  7. */
  8. public class IfDemo1 {
  9.     public static void main(String[] args) {
  10.         Scanner scanner = new Scanner(System.in);
  11.         System.out.println("请输入袜子的数量");
  12.         int count = scanner.nextInt();
  13.         double totalPrice = 0.0;    // 默认总价格初始值为0.0
  14.         double price = 4;       // 袜子的价格4元
  15.         // 条件判断: 输入的数量是否大于0
  16.         if (count > 0) {
  17.             totalPrice = count * price;
  18.             System.out.println("购买了" + count + "双袜子, 价格是" + totalPrice + "元");
  19.         }
  20.     }
  21. }
复制代码
运行结果:

案例:输入一个数字,如果能被10整除,则输出内容为:xx能被10整除。如果能被15整除,则输出内容为:xx能被15整除。
解决本题的关键点在于被10整除和被15整除的条件怎么计算。其实前面我们学过取余运算符,如果数值number能被10整除,那么可以写成number % 10 == 0;如果数值number能被15整除,那么可以写成number % 15 == 0。这两个布尔表达式可以写入到两个if语句中:
  1. import java.util.Scanner;
  2. /**
  3. * 使用if语句判断数字能否被10和15整除
  4. *
  5. * @author iCode504
  6. * @date 2023-11-07
  7. */
  8. public class IfDemo2 {
  9.     public static void main(String[] args) {
  10.         Scanner scanner = new Scanner(System.in);
  11.         System.out.println("请输入数字: ");
  12.         int number = scanner.nextInt();
  13.         // 整除10的条件:数字对10取余等于0
  14.         if (number % 10 == 0) {
  15.             System.out.println(number + "能被10整除");
  16.         }
  17.         // 整除15的条件:数字对15取余等于0
  18.         if (number % 15 == 0) {
  19.             System.out.println(number + "能被15整除");
  20.         }
  21.     }
  22. }
复制代码
输入不同的数字以后,会得到如下的运行结果:

案例:输入两个整数,如果输入的第一个数字比第二个数字大,那么执行两数交换,并将交换结果输出。否则不交换,正常输出两个数
本题的条件表达式是输入的两个数字的比较,无论数字大小比较结果如何,都需要将结果进行输出,我们可以将输出语句放到if语句后面执行。
两数交换有多种方式,较为稳妥的方式是再定义一个临时变量,用这个临时变量来接收第一个变量值,然后第二个变量值赋值给第一个变量,最后将临时变量的值赋值给第二个变量。
以下是示例代码:
  1. import java.util.Scanner;
  2. /**
  3. * 单分支if语句实现两数交换
  4. *
  5. * @author iCode504
  6. * @date 2023-11-11
  7. */
  8. public class IfDemo3 {
  9.     public static void main(String[] args) {
  10.         Scanner scanner = new Scanner(System.in);
  11.         System.out.println("请输入两个整数");
  12.         int number1 = scanner.nextInt();
  13.         int number2 = scanner.nextInt();
  14.         int temp = 0;       // 定义临时变量
  15.         if (number1 > number2) {    // 实现两数交换功能
  16.             temp = number1;
  17.             number1 = number2;
  18.             number2 = temp;
  19.         }
  20.         System.out.println("第一个数是: " + number1 + ", 第二个数是: " + number2);
  21.     }
  22. }
复制代码
运行结果:

当然,除了上述方式能实现两数交换,还有其他的方式。
方式一:使用加减法进行交换(推荐使用整数,浮点数不推荐,因为浮点数计算时会出现误差)
  1. int number1 = 3;
  2. int number2 = 2;
  3. number1 = number1 + number2;        // number1 = 3 + 2 = 5
  4. number2 = number1 - number2;        // number2 = 5 - 2 = 3
  5. number1 = number1 - number2;        // number1 = 5 - 3 = 2
复制代码
方式二:使用位运算符进行交换(推荐使用整数,此处涉及到二进制异或运算,异或运算可以查看这篇文章:入门篇-其之六-Java运算符(中)第四部分-位运算符
  1. int number1 = 3;
  2. int number2 = 2;
  3. number1 = number1 ^ number2;        // 3 ^ 2 = 1
  4. number2 = number1 ^ number2;        // 3 ^ 1 = 2
  5. number1 = number1 ^ number2;        // 1 ^ 2 = 3
复制代码
当然,上述三种方式我个人最推荐的还是第一种定义临时变量的方式,这种方式对处理浮点类型的数进行交换很友好,如果使用了下面两种方式的话,可能会在计算过程中出现精度损失的问题。后两种方式的好处是不需要定义第三个变量,只需要进行一系列运算即可完成整数值的交换。
二、if-else双分支语句

前面讲过的单分支if语句只有在布尔表达式为true的时候执行其内部的内容,但是如果在布尔表达式为false的时候不会做任何事情。为了解决上述问题,Java为我们提供了if-else双分支语句。以下是双分支if-else语句代码结构:
  1. if (条件表达式) {
  2.     执行代码1...
  3. } else {
  4.     执行代码2...
  5. }
复制代码
如果条件表达式的值是true,那么就执行if内部的语句,如果条件表达式为false,此时就进入else代码块。执行流程图如下:

案例:我们还是以上述买袜子为例,最近双十一打折,如果买了10双及以上袜子,此时每双袜子打八折优惠,否则打九折优惠(袜子的价格假设是4元/双)。
题目中的条件表达式在于要买的袜子数量是否大于等于10,如果是,价格打8折,否则打9折,使用刚刚讲到的if-else语句即可搞定。
当然,这道题中还有一个隐藏的细节需要我们处理:输入袜子的数量需要大于0,否则判定为无效,这个可以使用单分支if语句就可以搞定。
以下是示例代码:
  1. import java.util.Scanner;
  2. /**
  3. * if-else双分支语句
  4. *
  5. * @author iCode504
  6. * @date 2023-11-11
  7. */
  8. public class IfDemo4 {
  9.     public static void main(String[] args) {
  10.         Scanner scanner = new Scanner(System.in);
  11.         System.out.println("请输入要购买的袜子数量");
  12.         int count = scanner.nextInt();
  13.         double price = 4;       // 每双袜子的价格
  14.         double totalPrice = 0.0;    // 默认总价格为0.0
  15.         // 需要保证输入的袜子数量要大于0
  16.         if (count > 0) {
  17.             // 如果袜子的数量大于10,此时每双袜子的价格为8折,即每双袜子的价格乘以0.8,九折的计算方式和上述内容同理
  18.             if (count >= 10) {
  19.                 totalPrice = price * 0.8 * count;
  20.             } else {
  21.                 totalPrice = price * 0.9 * count;
  22.             }
  23.         }
  24.         System.out.println("购买" + count + "双袜子,双十一期间购买价格是" + totalPrice + "元");
  25.     }
  26. }
复制代码
运行结果(可能会出现浮点数计算不准确的情况,属于正常现象):

三、if-else if-else多分支语句

双分支的if-else语句对于条件表达式为true和false的时候比较适用,但是如果对于一个问题而言,此时经过分析可能存在多个条件表达式时,if-else语句并不能很好地完成任务,此时Java为我们提供了另一种分支语句:if-else if-else语句,其语法格式如下:
  1. if (条件表达式1) {
  2.         执行代码1...
  3. } else if (条件表达式2) {
  4.         执行代码2...
  5. } else if (条件表达式3) {
  6.         执行代码3...
  7. } ...
  8.   else if (条件表达式n) {
  9.         执行代码n...      
  10. } else {
  11.           不符合上述所有条件表达式时执行else代码...
  12. }
复制代码
以上述语法格式为例,其执行顺序为:
多分支的if-else if-else语句中,你可以写任意个else if,每个else if需要写上条件表达式。
当然,最后的else也是可选的,if和else-if搭配使用也是可以的。以下是执行流程图:

案例:已知长春的地铁/轻轨票价标准如下
假设从1号线红嘴子地铁站到8号线广通路轻轨站的距离是31.4公里,从2号线汽车公园地铁站到2号线东方广场地铁站的距离是20.5公里,从4号线长春站北轻轨站到4号线天工路轻轨站的距离是16.3公里。
输入上述里程,利用程序计算出乘坐轨道交通所需要的票价。
上述题目中出现了多个条件判断,每个条件判断执行内容都不相同,使用多分支语句if-else if-else语句比较合适。题目中有一个隐藏条件,输入里程数不能为负数,当然这个条件也直接写入条件判断即可。
如果乘坐轨道交通的里程超过35公里以后,每增加10公里,增加1元。例如:乘坐45公里就要在35公里对应的票价6元的基础上再增加1元,当然,55公里、65公里依次类推。假设称作里程为44.9公里,此时收费标准仍为35公里的票价。
针对上述问题,我们可以在代码中进一步呈现:
  1. import java.util.Scanner;
  2. /**
  3. * if-else if-else多分支语句的使用
  4. *
  5. * @author iCode504
  6. * @date 2023-11-14
  7. */
  8. public class ElseIfDemo1 {
  9.     public static void main(String[] args) {
  10.         Scanner scanner = new Scanner(System.in);
  11.         System.out.print("请输入里程数: ");
  12.         // 里程数使用double类型比较合适,因为题目中涉及到距离的使用到了小数
  13.         double distance = scanner.nextDouble();
  14.         int price = 0;
  15.         if (distance <= 0) {
  16.             System.out.println("无效里程");
  17.         } else if (distance > 0 && distance <= 7) {
  18.             price = 2;
  19.         } else if (distance > 7 && distance <= 13) {
  20.             price = 3;
  21.         } else if (distance > 13 && distance <= 19) {
  22.             price = 4;
  23.         } else if (distance > 19 && distance <= 27) {
  24.             price = 5;
  25.         } else if (distance > 27 && distance <= 35) {
  26.             price = 6;
  27.         } else {
  28.             // 超过35公里的需要额外进行处理
  29.             price = 6;      // 35公里对应的票价
  30.             // 计算多余的里程
  31.             // 这里需要进行强制类型转换的目的有两个:
  32.             // 1. 最后计算票价的price是int类型
  33.             // 2. 针对类似在35~45公里之间的里程后续的票价计算处理
  34.             int additionalDistance = (int) (distance - 35);
  35.             // 计算票价
  36.             price = price + additionalDistance / 10;
  37.         }
  38.         System.out.println("乘坐长春轨道交通里程" + distance + "公里,票价" + price + "元");
  39.     }
  40. }
复制代码
运行结果:

虽然运行结果符合我们的预期,但是我只能说:这样的代码写的非常糟糕!!!这段代码中if的嵌套层数达到了三层,事实上if嵌套两层以上可读性就大打折扣了。
我们可以使用Java数组、循环和数组方法对此问题做进一步处理(小白可以跳过这一部分)。
  1. if (条件表达式1) {
  2.     if (条件表达式2) {
  3.         执行代码1...
  4.     } else {
  5.             执行代码2...
  6.     }
  7. } else {
  8.     if (条件表达式3) {
  9.             执行代码3...
  10.     } else {
  11.             执行代码4...
  12.     }
  13. }
复制代码
运行结果:

五、switch语句

if-else if-else多分支语句可以用于多个条件表达式的判断,我们可以写非常多的else if,然而过多的else if可能会导致代码的可读性变差。
Java为我们提供了swtich语句在一定程度上可以简化多条件分支。以下是switch的语法结构:
  1. import java.util.Scanner;
  2. /**
  3. * if的嵌套--三个数字排列
  4. *
  5. * @author iCode504
  6. * @date 2023-11-23
  7. */
  8. public class IfDemo5 {
  9.     public static void main(String[] args) {
  10.         Scanner scanner = new Scanner(System.in);
  11.         System.out.print("请输入三个整数: ");
  12.         int number1 = scanner.nextInt();
  13.         int number2 = scanner.nextInt();
  14.         int number3 = scanner.nextInt();
  15.         if (number1 > number2) {
  16.             if (number2 > number3) {
  17.                 System.out.println("三个数从大到小的排序是: " + number1 + " " + number2 + " " + number3);
  18.             } else {
  19.                 if (number1 > number3) {
  20.                     System.out.println("三个数从大到小的排序是: " + number1 + " " + number3 + " " + number2);
  21.                 } else {
  22.                     System.out.println("三个数从大到小的排序是: " + number3 + " " + number1 + " " + number2);
  23.                 }
  24.             }
  25.         } else {
  26.             if (number2 < number3) {
  27.                 System.out.println("三个数从大到小的排序是: " + number3 + " " + number2 + " " + number1);
  28.             } else {
  29.                 if (number1 > number3) {
  30.                     System.out.println("三个数从大到小的排序是: " + number2 + " " + number3 + " " + number1);
  31.                 } else {
  32.                     System.out.println("三个数从大到小的排序是: " + number2 + " " + number1 + " " + number3);
  33.                 }
  34.             }
  35.         }
  36.     }
  37. }
复制代码
1. switch语句中表达式的计算结果、值1、值2、...、值n的数据类型必须要保持一致。支持的数据类型包括:byte、short、int、char、字符串类型String(JDK 7新特性)、枚举类型(后续会讲到,JDK 7新特性)。
2. 如果表达式的计算结果和case中某个值相等时,就会执行这个case内的代码。
3. switch语句中的default是可选的,它的作用是当表达式的计算结果和所有case的值都不相等时才会执行default语句,如果default语句不存在时,所有的case对应的值和判定值都不相等时,跳出switch语句。
4. break的作用是跳出switch语句(break关键字还会在循环中遇到),在每一个case对应的代码块后面写上break是个好习惯。
如果case中不加break,此时switch语句会出现穿透性,即当某一个case执行完成后,它会继续执行下面其他的case。以下是一个是否使用break的案例:
案例:输入数字1~7,使用switch语句输出当前日期(假设7代表星期日)
  1. import java.util.Arrays;
  2. import java.util.Scanner;
  3. /**
  4. * 三数比较--按照从大到小的顺序排列
  5. *
  6. * @author iCode504
  7. * @date 2023-11-23
  8. */
  9. public class IfDemo6 {
  10.     public static void main(String[] args) {
  11.         Scanner scanner = new Scanner(System.in);
  12.         System.out.print("请输入三个数字: ");
  13.         Integer[] array = new Integer[3];
  14.         for (int i = 0; i < array.length; i++) {
  15.             array[i] = scanner.nextInt();
  16.         }
  17.         // 调用Arrays.sort方法对数组排序,排序规则从大到小(lambda表达式)
  18.         Arrays.sort(array, (o1, o2) -> o2 - o1);
  19.         System.out.println("三个数从大到小的排序是: " + array[0] + " " + array[1] + " " + array[2]);
  20.     }
  21. }
复制代码
运行结果:

很明显,输入数字3的时候,由于没有break,当执行case 3内部代码以后,它会向下执行其他case中的代码,直至default内的代码执行完毕为止。并且这段代码还有可以进一步修改的空间,以下是加入break并进行简化的代码:
  1. switch (表达式) {
  2.     case 值1:
  3.         执行代码1...
  4.         break;
  5.     case 值2:
  6.         执行代码2...
  7.         // break
  8.     case 值3:
  9.         执行代码3...
  10.         break;
  11.     ...
  12.     case 值n:
  13.         执行代码n...
  14.         break;
  15.     default:
  16.         上述条件都不适用执行代码...
  17. }
复制代码
运行结果:

从上述结果可以看出,使用break以后,就可以阻断switch穿透性。
switch语句执行流程如下图所示(每个case都带上break语句):

在了解了switch语句的基础上,我们再来讲解一个switch语句和if-else语句结合使用的案例:
案例:输入年份和月份,输出格式如下:xxxx年xx月有xx天。
常识:1、3、5、7、8、10、12恒定是31天;4、6、9、11恒定为30天。这几个月份我们可以利用switch的穿透性替换掉多条件的else if判断。
需要额外考虑的是:2月份的天数需要考虑年份是闰年还是平年,闰年能被400整除,例如:2000年,1600年是闰年,1900年就不是闰年。此外,如果不能被100整除,而能被4整除的也是闰年,例如:2020,2016,2004,2008年都是闰年。
结合上述分析,我们可以使用代码进一步复现:
  1. import java.util.Scanner;
  2. /**
  3. * switch语句--不加break--穿透性
  4. *
  5. * @author iCode504
  6. * @date 2023-11-15
  7. */
  8. public class SwitchDemo1 {
  9.     public static void main(String[] args) {
  10.         Scanner scanner = new Scanner(System.in);
  11.         System.out.println("请输入星期数(1~7), 7表示星期日");
  12.         int number = scanner.nextInt();
  13.         switch (number) {
  14.             case 1:
  15.                 String monday = "星期一";
  16.                 System.out.println("今天是" + monday);
  17.             case 2:
  18.                 String tuesday = "星期二";
  19.                 System.out.println("今天是" + tuesday);
  20.             case 3:
  21.                 String wednesday = "星期三";
  22.                 System.out.println("今天是" + wednesday);
  23.             case 4:
  24.                 String thursday = "星期四";
  25.                 System.out.println("今天是" + thursday);
  26.             case 5:
  27.                 String friday = "星期五";
  28.                 System.out.println("今天是" + friday);
  29.             case 6:
  30.                 String saturday = "星期六";
  31.                 System.out.println("今天是" + saturday);
  32.             case 7:
  33.                 String sunday = "星期日";
  34.                 System.out.println("今天是" + sunday);
  35.             default:
  36.                 System.out.println("无效日期");
  37.         }
  38.     }
  39. }
复制代码
运行结果:

以我个人的开发经验来看,使用switch语句的频率要比使用if语句要少很多,二者的执行效率基本上差不太多。
if可以编写更加灵活的条件表达式。比如:判断某个整数在[10, 20]区间内,此时使用if条件表达式可以写成if (number >= 10 && number = 628))来表达 x 小于 628。
七、知识点总结

流程控制之条件判断知识点总结如下图所示:
如需高清大图,请点击右侧链接下载文件:点我下载


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4