第三章 选择
3.1 引言
程序可以基于条件决定执行哪些语句。
和所有高级程序设计语言一样,Java也提供选择语句:在可选择的执行路径中做出选择的语句。如下便是一个简单的示例:
假设现在需要求一个圆的面积,变量radius为圆的半径。给radius赋一个负值,程序就会打印一个无效的结果。如果半径是一个负值,是不希望程序计算面积的,那么该如何处理这种情况呢?
if (radius < 0) {
System.out.println("输入不正确");
} else {
double area = radius * radius * 3.14159;
System.out.println("Area is" + area);
}
选择语句要用到的条件采用布尔表达式计算。布尔表达式是计算结果为布尔值true或者false的表达式。
3.2 boolean数据类型、值和表达式
boolean数据类型声明一个具有值true或者false的变量。
Java提供六种关系操作符(relational operator)(也称为比较操作符(comparison operator)),用于两个值的比较(假设表中的半径值为5)。下图列出了6个常用的关系操作符:
警告:相等的关系操作符是两个等号(==),而不是一个等号(=),后者是指赋值操作符比较的结果是一个布尔值:true(真)或false(假)。
true和false也是字面值、但是同时也是保留字但不是关键字。因此亦不能用作标识符。
3.3 if语句
if语句是一个构造,允许程序确定执行的可选路径。
Java有几种类型的选择语句:单分支if语句、双分支if-else语句、嵌套if语句、
分支if-else语句、switch语句和条件操作符。
下面是一个简单的表达式,用于判断数x的值是否大于5。
int x = 6;
if (x > 5) {
System.out.println("x大于5!");
}
3.4 双分支if-else语句
if-else语句根据条件是真或者是假,决定执行的路径。
下面是一个简单的示例,用于判断x是否大于5,x若大于5,则输出"YES",否则输出"NO"。
int x = 6;
if (x > 5) {
System.out.println("YES");
} else {
System.out.println("NO");
}
3.5 嵌套的if语句和多分支if-else语句
if语句可以在另外一个if语句中,形成嵌套的if语句。
if或if-else语句中的语句可以是任意合法的Java语句,甚至可以是其他的if或if-else语句。内层if语句称为是嵌套在外层if语句里的。内层if语句还可以包含其他的 if语句;事实上,对嵌套的深度没有限制。
例如,下面就是一个嵌套的示例:
int score = 75;
if (score >= 60) {
if(score >= 90) {
System.out.println("优秀");
} else {
System.out.println("及格");
}
} else {
System.out.println("不及格");
}
这段代码有必要解释一下,首先计算机会先判断if(score >= 60)
语句,显然score是大于60的,因此继续执行if (score >= 60) {}
的子语句,然后继续进行判断,执行if (score >= 90)
,显然小于,因此执行else
内的输出语句,打印“及格”。
上述代码还可以写成如下的多分支形式:
int score = 75;
if (score >= 90) {
System.out.println("优秀");
} else if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
效果一样。不再赘述。
3.6 常见错误和陷阱
以下是选择语句中常见的错误:忘记必要的括号,在错误的地方结束if语句,将==
错当作=
使用,悬空else分支。在if-else语句中重复的语句,以及测试double值的相等是常见的陷阱。
3.7 产生随机数
可以使用Math.random()
来获得一个0.0到1.0之间的随机double值,不包括 1.0。
需求:开发一让一年级学生练习加减法的程序。程序随机产生两个只有一位的整数number1和number2,且满足number1>=number2。程序向学生显示一个问题,例如“9 - 2 = ?”。当学生输入答案之后,程序会显示一个消息表示该答案是否正确。
思路:
- 产生两个一位整数number1和number2
- 如果number1<number2,交换numberl和number2
- 提示学生回答“what is number1-number2?”
- 检查学生的答案并且显示该答案是否正确。
具体实现:
package com.Javabook.Demo;
import java.util.Scanner;
public class P79_random {
public static void main(String[] args) {
//产生两个随机数number1和number2
int number1 = (int)(Math.random() * 10);
int number2 = (int)(Math.random() * 10);
//如果number1 < number2,交换二者
if (number1 < number2) {
int temp = number1;
number1 = number2;
number2 = temp;
}
//打印问题
System.out.println(number1 + " - " + number2 + " = ?");
Scanner sc = new Scanner(System.in);
int answer = sc.nextInt();
//判断结果
if (answer == number1 - number2) {
System.out.println("回答正确!");
} else {
System.out.println("回答错误!");
}
}
}
3.8 示例学习:计算体重指数
**需求:**身体质量指数(BMI)是基于体重和身高计算的健康测量。可以通过以千克为单位的体重除以以米为单位的身高的平方,得到BMI的值。针对20岁及以上年龄的人群他们的BMI值的说明如下所示。
编写程序,提示用户输人以磅为单位的体重,以及以英寸为单位的身高,然后显示BMI。注意:1磅是0.45359237千克,而1英寸是0.0254米。
思路:
1.读取体重和身高
2.计算BMI
3.根据BIM对应范围输出对应状态
具体实现:
package com.Javabook.Demo;
import java.util.Scanner;
public class P81_ComputeBMI {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//获取体重
System.out.print("请输入体重: ");
double weight = sc.nextDouble();
//获取身高
System.out.print("请输入身高:");
double height = sc.nextDouble();
//定义每磅多少千克以及每英寸多少米
final double KILOMETERS_PER_POUND = 0.45359237;
final double METERS_PER_INCH = 0.0254;
//计算BMI
double weightInKilometers = weight * KILOMETERS_PER_POUND;
double heightInMeter = height * METERS_PER_INCH;
double BMI = weightInKilometers / (heightInMeter * heightInMeter);
//打印结果
System.out.println("BMI是" + BMI);
if (BMI < 18.5) {
System.out.println("偏瘦!");
} else if (BMI >= 18.5 && BMI <= 24.9) {
System.out.println("正常!");
} else if (BMI >= 25 && BMI <= 29.9) {
System.out.println("超重!");
} else if (BMI >= 30 && BMI <= 39.9) {
System.out.println("过胖!");
}
}
}
3.9 示例学习:计算税率
**需求:**美国国家联邦个人收入所得税是基于纳税人登记的身份和可征税收入计算的。纳税人登记的身份有四种:单身纳税人、已婚共同或鳏寡纳税人、已婚单独纳税人和家庭户主纳税人。税率会每年变化。表3-2给出2009年的税率。也就是说,如果你是单身纳税人,可征税收入为10 000美元,那么可征税收入的前8350美元的税率为10%,而剩下的1650美元的税率为15%。所以,你该付的税金为1082.5美元。
你要编写一个程序来计算个人收入税。程序应该提示用户输入登记的身份以及可征税收人,然后计算出税款。输入0表示单身纳税人,1表示已婚共同纳税人,2为已婚单独纳税人,3为家庭户主纳税人。
对每个登记的身份都有六种税率。每个税率应用于某个可征税收入范围内。例如:对于有可征税收入400000美元的单身登记人来说,8350美元的税率是10%,从8350到33950之间税率是15%,从33950到82250之间税率是25%,从82250到171550之间税率是28%,从171550到372950之间税率是33%,而从372950到400000之间税率是35%。
思路:
1.获取税收入类型
2.获取收入
3.计算税收
4.打印结果
具体实现:
package com.Javabook.Demo;
import java.util.Scanner;
public class P83_ComputeTax {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//获取纳税人类型,其中:1-单身纳税人,2-已婚共同纳税人或符合条件的鳏寡,3-已婚单独纳税人,4-家庭户主纳税人
System.out.println("(1代替单身纳税人,2代替已婚共同纳税人或符合条件的鳏寡,3代替已婚单独纳税人,4代替家庭户主纳税人)");
System.out.print("请输入纳税人类型:");
int status = sc.nextInt();
//获取收入
System.out.print("请输入收入:");
int income = sc.nextInt();
//计算应交税款
double tax = 0;
if (status == 1) {
//计算单身纳税人应交税款
if (income <= 8350) {
tax = income * 0.10;
} else if (income <= 33950) {
tax = 8350 * 0.10 + (income - 8350) * 0.15;
} else if (income <= 82250) {
tax = 8350 * 0.10 + (33950 - 8350) * 0.15 + (income - 33950) * 0.25;
} else if (income <= 171550) {
tax = 8350 * 0.10 + (33950 - 8350) * 0.15 + (82250 - 33950) * 0.25 + (income - 82250) * 0.28;
} else if (income <= 372950) {
tax = 8350 * 0.10 + (33950 - 8350) * 0.15 + (82250 - 33950) * 0.25 + (171550- 82250) * 0.28 + (income - 171550) * 0.33;
} else {
tax = 8350 * 0.10 + (33950 - 8350) * 0.15 + (82250 - 33950) * 0.25 + (171550- 82250) * 0.28 + (372950 - 171550) * 0.33 + (income - 372950) * 0.35;
}
} else if (status == 2) {
//计算已婚共同纳税人或符合条件的鳏寡应交税款
} else if (status == 3) {
//计算已婚单独纳税人应交税款
} else if (status == 4) {
//计算家庭户主纳税人应交税款
} else {
System.out.println("错误:纳税人编号无效!!!");
System.exit(1);
}
//打印结果
System.out.println("应交税款为:" + (int)(tax * 100) / 100.0);
}
}
3.10 逻辑操作符
逻辑操作符!
、&&
、||
和^
可以用于产生复合布尔表达式。
有时候,是否执行一条语句是由几个条件的组合来决定的。可以使用逻辑操作符组合这些条件。逻辑操作符(logical operator)也称为布尔操作符(boolean operator),对布尔值进行的运算并创建新的布尔值。
下面列出四个逻辑操作符的真值表:
警告:从数学的角度看,表达式1<=numberOfDaysInAMonth<=31
是正确的。但是,在Java中它是错的,因为1<=numberOfDaysInAMonth
得到的是一个布尔值的结果,它是不能和31进行比较的。这里的两个操作数(一个布尔值和一个数值)是不兼容的。正确的Java表达式是:
28 <= numberOfDaysInAMonth && numberOfDaysInAMonth <= 31
3.11 示例学习:判断闰年
**需求:**如果某年可以被4整除而不能被100整除,或者可以被 400整除,那么这一年就是闰年。下面请写一个程序来判断某年份是否为闰年。
思路:
1.获取年份
2.判断是否为闰年
3.输出结果
具体实现:
package com.Javabook.Demo;
import java.util.Scanner;
public class P88_LeapYear {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//获取年份
System.out.print("请输入年份: ");
int year = sc.nextInt();
//判断是否为闰年
boolean isLeapYear = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
//打印结果
System.out.println(year + " 是闰年吗?" + isLeapYear);
}
}
3.12 示例学习:彩票
**需求:**开发一个玩彩票的游戏,程序随机地产生一个两位数的彩票,提示用户输人一个两位数,然后按照下面的规则判定用户是否能赢:
- 如果用户的输入从顺序到数字都匹配彩票数字,奖金为10000美元。
- 如果用户输人的所有数字匹配彩票的所有数字,奖金为3000美元。
- 如果用户输人的一个数字匹配彩票的一个数字,奖金为1000美元。
请注意,两位数字中可能有一位为0。如果一个数小于10,我们假设这个数字以0开始,从而构建一个两位数。例如,程序中数字8被作为08处理,数字0作为00处理。
思路:
1.产生一个两位数
2.获取用户输入的两位数
3.判断是否一致
具体实现:
package com.Javabook.Demo;
import java.util.Scanner;
public class P89_Lottery {
public static void main(String[] args) {
//生成一个两位数彩排编号
int lottery = (int)(Math.random() * 100);
//获取用户输入的彩票号
Scanner sc = new Scanner(System.in);
System.out.print("请输入您所拥有的两位彩票编码: ");
int guess = sc.nextInt();
//获取生成的彩票编码的两个数
int lotteryDigit1 = lottery / 10;
int lotteryDigit2 = lottery % 10;
//获取用户所拥有的编码的两个数
int guessDigit1 = guess / 10;
int guessDigit2 = guess % 10;
//打印中奖号码
System.out.println("中奖号码是:" + lottery);
//判断用户中奖情况
if (guess == lottery) {
System.out.println("您中得10,000美元");
} else if (guessDigit1 == lotteryDigit2 && guessDigit2 == lotteryDigit1) {
System.out.println("您中得3,000美元");
} else if (guessDigit1 == lotteryDigit1
|| guessDigit1 == lotteryDigit2
|| guessDigit2 == lotteryDigit1
|| guessDigit2 == lotteryDigit2) {
System.out.println("您中得1,000美元");
} else {
System.out.println("很抱歉,您尚未中得任何奖金!");
}
}
}
3.13 switch语句
switch语句基于变量或者表达式的值来执行语句。
Java提供switch语句来有效地处理多重条件的问题。
switch语句必须遵从下述规则:
①switch 表达式必须能计算出一个 char、byte、short、int或者String型值,并且必须用括号括住。(char和string类型将在下一章介绍。)
②value1,…,valueN必须与switch表达式的值具有相同的数据类型。注意va1ue1,…,valueN都是常量表达式,也就是说这里的表达式是不能包含变量的,例如,不允许出现 1+x。
③当 switch 表达式的值与case语句的值相匹配时,执行从该 case 开始的语句,直到遇到一个break语句或到达该switch语句的结束。
④默认情况(defau1t)是可选的,当没有一个给出的case与switch表达式匹配时则执行该操作。
⑤关键字 break是可选的。break语句会立即终止 switch 语句。
警告:不要忘记在需要的时候使用break语句。一旦匹配其中一个case,就从匹配的case处开始执行,直到遇到break语句或到达switch语句的结束。这种现象称为落空行为(fall-through behavior)。
3.14 条件操作符
条件操作基于一个条件计算表达式的值。
你可能想为受某些条件限制的变量赋值。例如:下面的语句在x大于0时给y赋值 1;当x小于等于0时给y赋值 -1。
if (x > 0) {
y = 1;
} else {
y = -1;
}
或者,如以下示例所示,你可以使用条件操作符来获得相同的结果。
y = (x > 0) ? 1 : -1;
符号?和:一起出现,称为条件操作符(也称为三元操作符,因为使用了三个操作数。这是 Java 中唯一的一个三元操作符)。
3.15 操作符的优先级和结合规则
操作符的优先级和结合规则确定了操作符计算的顺序。
下图是操作符的优先级示意图: