在上一章,我们开发了一个将英制单位转换成公制单位的程序,如果我们希望该程序更实用一些,实现英制单位(英寸)和公制单位(厘米)的互换,那么代码又该如何编写呢?有一点可以肯定,我们需要在程序中设置决策条件,如果输入的单位是英寸,转换的目标就是厘米;如果输入的单位是厘米,转换的目标就是英寸。为此,我们需要构造分支结构,让程序中有两条执行路径。代码如下所示:
package com.lovo;
import java.util.Scanner;
public class MyConverter {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("输入: ");
double length = sc.nextDouble();
String unit = sc.next();
if(unit.equals("英寸")) {
System.out.printf("%f英寸 = %f厘米\n", length, length * 2.54);
}
else if(unit.equals("厘米")) {
System.out.printf("%f厘米 = %f英寸\n", length, length / 2.54);
}
else {
System.out.println("无法处理的单位!");
}
sc.close();
}
}
输入: 13 厘米
13.000000厘米 = 5.118110英寸
输入: 3.9 英寸
3.900000英寸 = 9.906000厘米
注意:输入的时候,13和厘米之间应该放置一个空格作为分隔符,否则上面的程序无法将长度和单位分别读取出来。
在上面的代码中,我们使用了一种叫做if...else...的结构,if是Java中设置条件的关键字,后面的圆括号中会设置一个条件,如果条件成立(true),则执行if后面花括号中的代码;如果条件不成立(false),就执行else后面花括号中的代码。当然也可以在else后面再用if设置条件,条件成立和不成立再次分成两条不同的执行路径。
上面的代码中,我们用到了一种新的类型String,在Java中String是表示字符串的对象类型,String对象有很多的属性和方法,刚才使用的equals方法就是用于比较两个字符串内容是否相同的方法。
任务:现在你回到国内工作,要为你所在的公司开发薪资管理系统。你的工作是编写个人所得税计算工具。在我国,个人所得税的起征点是3500元,计算公式是:
个人所得税 = (工资收入 - 五险一金 - 个税起征点) * 税率 - 速算扣除数
其中,税率和速算扣除数可以查下表得到:
由于不同的地区不同的企业对五险一金的计算方式有所差异,我们在程序中用输入的方式指定输入五险一金的金额。
代码如下所示:
package com.lovo;
import java.util.Scanner;
public class TaxCalculator {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("请输入工资: ");
double salary = sc.nextDouble();
System.out.print("请输入五险一金: ");
double insurance = sc.nextDouble();
double base = salary - insurance - 3500;
double tax = 0;
if(base <= 0) {
tax = 0;
}
else if(base <= 1500) {
tax = base * 0.03;
}
else if(base <= 4500) {
tax = base * 0.1 - 105;
}
else if(base <= 9000) {
tax = base * 0.2 - 555;
}
else if(base <= 35000) {
tax = base * 0.25 - 1005;
}
else if(base <= 55000) {
tax = base * 0.3 - 2755;
}
else if(base <= 80000) {
tax = base * 0.35 - 5505;
}
else {
tax = base * 0.45 - 13505;
}
System.out.println("应缴纳个人所得税:" + tax);
sc.close();
}
}
事实上,要构造分支结构还有一种方式,就是使用switch...case...default...结构,这是C、C++和Java中构造多分支结构的一种方式。但是需要注意的是这种结构只能进行等值判断,而且switch结构在JDK 1.5以前的版本能够处理的只有byte(字节型)、short(短整型)、int(整型)、char(字符型),Java 5对switch进行了增强,可以处理枚举(enum)类型;Java 7对switch进行了再次增强,可以处理字符串(String)类型。swtich结构中的每个case就是一个分支,通常每个case后面都有一个break来避免执行完一个case后又进入下一个case。通常,在最后一个case之后可以放置default,当前面的case都没有匹配成功时,则会执行default中的代码,但default并不是必须的。
下面的例子模拟将一颗色子投掷6000次,统计每一面出现的次数。
package com.lovo;
public class DiceStatistic {
public static void main(String[] args) {
int f1, f2, f3, f4, f5, f6;
f1 = f2 = f3 = f4 = f5 = f6 = 1;
for(int i = 1; i <= 6000; i++) {
switch(roll()) {
case 1: f1++; break;
case 2: f2++; break;
case 3: f3++; break;
case 4: f4++; break;
case 5: f5++; break;
case 6: f6++; break;
}
}
System.out.println("1点出现了" + f1 + "次");
System.out.println("2点出现了" + f2 + "次");
System.out.println("3点出现了" + f3 + "次");
System.out.println("4点出现了" + f4 + "次");
System.out.println("5点出现了" + f5 + "次");
System.out.println("6点出现了" + f6 + "次");
}
public static int roll() {
return (int) (Math.random() * 6 + 1);
}
}
循环结构和分支结构是构造程序逻辑最重要的结构,Java中有三种类型的循环:while循环、do...while...循环和刚才代码中的for循环。其中,while循环和do...while...循环最大的差别在于后者会无条件的执行一次,再看循环条件是否成立来决定是否继续循环。而for循环的圆括号中两个分号隔开了三个部分,第一部分叫初始语句,只在第一次循环时执行一次,以后就再也不执行了;第二部分叫循环条件,是一个布尔值,布尔值为true则执行循环体,布尔值为false则结束循环;第三部分叫步进语句,相当于循环体中的最后一条语句,每循环一次就执行一次。下面用三段代码分别展示三种循环,做的事情都是从1到100求和。
Sum1.java (while循环)
package com.lovo;
public class Sum1 {
public static void main(String[] args) {
int sum = 0;
int i = 1;
while(i <= 100) {
sum += i++; // 先将i的值累加到sum上再将i加1
}
System.out.println("SUM = " + sum);
}
}
package com.lovo;
public class Sum2 {
public static void main(String[] args) {
int sum = 0;
int i = 1;
do {
sum += i++; // 先将i的值累加到sum上再将i加1
} while(i <= 100);
System.out.println("SUM = " + sum);
}
}
package com.lovo;
public class Sum3 {
public static void main(String[] args) {
int sum = 0;
for(int i = 1; i <= 100; i++) {
sum += i;
}
System.out.println("SUM = " + sum);
}
}