当使用双精度浮点数时,if else语句的替代方案是什么?

3

根据薪资,我需要为我的员工对象分配特定的税率。 薪水是由yearlySalary定义的,这是一个双精度浮点数,因此我无法使用switch语句。 我改用if / else:

public int getSalaryRank() {
    if(yearlySalary <= 60000.00) {
        salaryRank = 1;
    } else if(yearlySalary > 60000.00 && yearlySalary <= 80000.00) {
        salaryRank = 2;
    } else if(yearlySalary > 80000.00 && yearlySalary <= 100000.00) {
        salaryRank = 3;
    } else if(yearlySalary > 100000.00 && yearlySalary <= 125000.00) {
        salaryRank = 4;
    } else {
        salaryRank = 5;
    } return salaryRank; }

我将根据等级稍后指定税率。有更好的写法吗?


4
请使用BigDecimal代替。 - Luiggi Mendoza
1
所有的>条件都是多余的 - 每行的else语句都保证了你使用>运算符进行检查。而且请不要把double用于货币! - Dawood ibn Kareem
话虽如此,你的问题似乎暗示了 switch 比 if/else 块更好。其实并不是这样。switch 通常是设计不良的标志,并且是一种危险的结构(比如穿透等)。 - JB Nizet
1
return 1 + new TreeSet(Arrays.asList(60000.00, 80000.00, 100000.00, 125000.00)).headSet(yearlySalary, true).size(); - Dawood ibn Kareem
1
这有点玩笑,我不认为我会认真使用这个解决方案。但是它(以及@AlexWien的解决方案)比这里的其他解决方案具有优势,因为您可以从属性文件、数据库或其他地方获取值列表;而不是硬编码有4个不同的阈值,这可能会改变。我的最佳建议是做两件事。切换到使用“BigDecimal”,然后采用@AlexWien的解决方案。 - Dawood ibn Kareem
显示剩余3条评论
4个回答

4
考虑使用一个 while 循环遍历工资限制的列表或数组。

3
你可以简化它,像这样:

public int getSalaryRank() {
    int salaryRank;

    if(yearlySalary <= 60000.00) {
        return  1;
    } 

    if(yearlySalary <= 80000.00) {
        return 2;
    } 

    if(yearlySalary <= 100000.00) {
        return 3;
    } 

    if(yearlySalary <= 125000.00) {
       return 4;
    } 

    return 5

}

左侧的所有检查都是不必要的,因为语句按顺序执行。此外,您可以删除else语句并直接返回salaryrank。另外,在处理金钱时,永远不要使用浮点数。请改用BigDecimal。
编辑:考虑到AlexWien关于多个退出点的评论,这可能是更好的解决方案:
public int getSalaryRank() {
        if(yearlySalary <= 60000.00) {
            salaryRank = 1;
        } else  if(yearlySalary <= 80000.00) {
            salaryRank = 2;
        } else if(yearlySalary <= 100000.00) {
            salaryRank = 3;
        } else if(yearlySalary <= 125000.00) {
           salaryRank = 4;
        } else {
           salaryRank = 5;
        }  

        return salaryRank;

    }

多个返回值是从用户Tony复制的,但这种写法不好,因为现在有5个返回语句。尝试启用checkstyle。(不利于调试) - AlexWien
多个退出点可能不好,但对于这样一个简单的方法来说呢? - Svetlin Zarev
是的,因为在返回之前无法设置断点。但这取决于个人观点。所以我没有给它点踩。 - AlexWien
@AlexWien 自从看到你在一个方法中使用多个返回语句的评论后,我就不再这样做了。但是我想知道,为什么这是一种不好的编程习惯呢?当我谷歌搜索时,我找到了这个链接:http://programmers.stackexchange.com/a/118717 - Honinbo Shusaku
@Abdul,这是不好的两个原因:首先很难设置断点,其次,在这种情况下使用return并不能使代码更简单,最后,自动计算的复杂度(使用SW-Metrics)将非常高(2的幂次方(else子句的数量))。 - AlexWien

2
如何呢:
public int getSalaryRank() 
{
    if(yearlySalary <= 60000.00) return 1;
    if(yearlySalary <= 80000.00) return 2;
    if(yearlySalary <= 100000.00) return 3;
    if(yearlySalary <= 125000.00) return 4;
    return 5;
}

2

如果之前的任何一个if语句为真,那么您的程序将不会执行else语句。因此,您可以利用这一点,省略以下内容:yearlySalary > 60000.00 &&

if(yearlySalary <= 60000.00) {
    salaryRank = 1;
} else if(yearlySalary <= 80000.00) {
    salaryRank = 2;
}

此外,double类型并不特别精确。它们是浮点数,这意味着您无法准确地保存例如0.1的值。请自行查阅。BigDecimal是一种更适合货币使用的类型。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接