关于Table Driven Approach的一篇非常好的文章:
http://www.codeproject.com/Articles/42732/Table-driven-Approach
package com.ljn.base;
import java.util.Random;
public class TableDriven {
public static void main(String[] args) {
//实例1:计算税收
System.out.println(TaxCalculator.findTax(4300));
//实例2:计算成绩等级
for (int i = 0; i < 10; i++) {
double remark = new Random().nextInt(100) + 0.0;
System.out.println(remark + ", " + Grade.findGrade(remark));
}
}
}
/**实例0
* 表驱动法最直观的用法
* 代替if语句:
* if (January) return 31;
* ...
* if (December) return 31;
* 在一些查询算法中,表驱动法可以作为一种“以空间换时间”的方案
*/
class DayCountInMonth {
private static final int[] DAY_TABLE = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
//略去参数合法性检查。假设月份从1开始
public static int getDayCount(int month, boolean leapYear) {
int diff = (leapYear && (month == 2)) ? 1 : 0;
return DAY_TABLE[month - 1] + diff;
}
}
/**实例1
我国税法规定,公民每月工资、薪金收入总税超过1600元者应缴纳个人所得税。
收入总额减去免征基数后剩余部分称为应纳税所得额,应纳税所得额按下表规定的超额累进税率计算应缴纳的个人所得税
级别 应纳税所得额 税率%
1 不超过500元的 5
2 超过500元至2000元的部分 10
3 超过2000元至5000元的部分 15
4 超过5000元至20000元的部分 20
5 超过20000元的部分 25
例如:张三某月总收入4300元,减去免征基数1600元,则应纳税所得额为2700元。
2700元符合1,2,3级纳税标准,故张三本月总收入应纳税总额由三部分组成:
不超过500元的部分为500元,按5%税率计算应纳税25元;
而500元至2000元的部分为1500元,按10%的税率计算应纳税150元;
超过2000元的部分为2700-2000=700元,按15%税率计算应纳税105元,
三者之和为25元+150元+105元=280元
*/
class TaxCalculator {
public static final int BASE = 1600;
private static final int[][] TAX_BRACKETS = {
{500, 5},
{2000, 10},
{5000, 15},
{20000, 20},
{Integer.MAX_VALUE, 25},
};
public static double findTax(int rawIncome) {
if (rawIncome < 0 || rawIncome <= BASE) {
return 0;
}
int income = rawIncome - BASE;
double tax = 0;
int pre = 0;
for (int[] bracket : TAX_BRACKETS) {
int incomeLimit = bracket[0];
int rate = bracket[1];
tax += (min(incomeLimit, income) - pre ) * (rate / 100.0) ;
if (income <= incomeLimit) {
break;
}
pre = incomeLimit;
}
return tax;
}
private static int min(int x, int y) {
return x < y ? x : y;
}
}
/**实例2
成绩等级
*/
class Grade {
private static final double[] REMARK = {50.0, 65.0, 75.0, 90.0, 100.0};
private static final String[] GRADE = {"F", "D", "C", "B", "A"}; //maybe enum is better
//略去参数合法性检查
public static final String findGrade(double remark) {
String grade = "A";
for (int i = 0, len = REMARK.length; i < len; i++) {
double remarkLimit = REMARK[i];
if (remark < remarkLimit) {
grade = GRADE[i];
break;
}
}
return grade;
}
}