如何在 BigDecimal 上使用 >、=、< 等比较运算符

How to use comparison operators like >, =, < on BigDecimal

我有一个域 class,其 unitPrice 设置为 BigDecimal 数据类型。现在我正在尝试创建一种方法来比较价格,但似乎我不能在 BigDecimal 数据类型中使用比较运算符。我必须更改数据类型还是有其他方法?

Class BigDecimal 的每个对象都有一个方法 compareTo 可以用来将它与另一个 BigDecimal 进行比较。 compareTo 的结果然后根据您的需要与 > 0== 0< 0 进行比较。阅读文档,你会发现。

运算符==<>等只能用于原始数据类型,如intlongdouble 或他们的包装器 类 像 IntegerDouble.

来自 compareTo 的文档:

Compares this BigDecimal with the specified BigDecimal.

Two BigDecimal objects that are equal in value but have a different scale (like 2.0 and 2.00) are considered equal by this method. This method is provided in preference to individual methods for each of the six boolean comparison operators (<, ==, >, >=, !=, <=). The suggested idiom for performing these comparisons is: (x.compareTo(y) <op> 0), where <op> is one of the six comparison operators.

Returns: -1, 0, or 1 as this BigDecimal is numerically less than, equal to, or greater than val.

使用BigDecimal的compareTo方法:

public int compareTo(BigDecimal val) Compares this BigDecimal with the specified BigDecimal.

Returns:
-1, 0, or 1 as this BigDecimal is numerically less than, equal to, or greater than val.

BigDecimal isn't a primitive, so you cannot use the <, > operators. However, since it's a Comparable, you can use the compareTo(BigDecimal)效果相同。例如:

public class Domain {
    private BigDecimal unitPrice;

    public boolean isCheaperThan(BigDecimal other) {
        return unitPirce.compareTo(other.unitPrice) < 0;
    }

    // etc...
}

您可以使用名为 compareTox.compareTo(y) 的方法。如果 x 和 y 相等,它将 return 0,如果 x 大于 y,则为 1,如果 x 小于 y,则为 -1

简而言之:

firstBigDecimal.compareTo(secondBigDecimal) < 0 // "<"
firstBigDecimal.compareTo(secondBigDecimal) > 0 // ">"    
firstBigDecimal.compareTo(secondBigDecimal) == 0 // "=="  
firstBigDecimal.compareTo(secondBigDecimal) >= 0 // ">="    

使用 IBM 的 com.ibm.etools.marshall.util.BigDecimalRange util class 可以比较 if BigDecimal in range.

boolean isCalculatedSumInRange = BigDecimalRange.isInRange(low, high, calculatedSum);

以下是所有六个布尔比较运算符(<、==、>、>=、!=、<=)的示例:

BigDecimal big10 = new BigDecimal(10);
BigDecimal big20 = new BigDecimal(20);

System.out.println(big10.compareTo(big20) < -1);  // false
System.out.println(big10.compareTo(big20) <= -1); // true
System.out.println(big10.compareTo(big20) == -1); // true
System.out.println(big10.compareTo(big20) >= -1); // true
System.out.println(big10.compareTo(big20) > -1);  // false
System.out.println(big10.compareTo(big20) != -1); // false

System.out.println(big10.compareTo(big20) < 0);   // true
System.out.println(big10.compareTo(big20) <= 0);  // true
System.out.println(big10.compareTo(big20) == 0);  // false
System.out.println(big10.compareTo(big20) >= 0);  // false
System.out.println(big10.compareTo(big20) > 0);   // false
System.out.println(big10.compareTo(big20) != 0);  // true

System.out.println(big10.compareTo(big20) < 1);   // true
System.out.println(big10.compareTo(big20) <= 1);  // true
System.out.println(big10.compareTo(big20) == 1);  // false
System.out.println(big10.compareTo(big20) >= 1);  // false
System.out.println(big10.compareTo(big20) > 1);   // false
System.out.println(big10.compareTo(big20) != 1);  // true

讨论

该线程有很多答案表明 BigDecimal.compareTo(BigDecimal) method is the one to use to compare BigDecimal instances. I just wanted to add for anyone not experienced with using the BigDecimal.compareTo(BigDecimal) method: Be careful with how you create your BigDecimal 个实例。例如:

  • new BigDecimal(0.8) 将创建一个 BigDecimal 实例,其值 而不是 恰好 0.8 并且其比例为 50+,
  • new BigDecimal("0.8") 将创建一个 BigDecimal 实例,其值 恰好 0.8 并且比例为 1.

这两个BigDecimal instances are unequal according to the BigDecimal.compareTo(BigDecimal)方法是因为当scale不限制小数点后他们的值是不相等的

总结

首先,请注意使用 BigDecimal(String val) 构造函数或 BigDecimal.valueOf(double val) 方法而不是 BigDecimal(double val) 构造函数创建 BigDecimal 实例。其次,请注意,您可以限制 BigDecimal instances prior to comparing them by means of the BigDecimal.setScale(int newScale, RoundingMode roundingMode) 方法的规模。

您可以按照此实用程序静态方法和运算符枚举来比较两个数字:

public static boolean check(BigDecimal firstNum, Operator operator, BigDecimal secondNum) {
    switch (operator) {
        case EQUALS:
            return firstNum.compareTo(secondNum) == 0;
        case LESS_THAN:
            return firstNum.compareTo(secondNum) < 0;
        case LESS_THAN_OR_EQUALS:
            return firstNum.compareTo(secondNum) <= 0;
        case GREATER_THAN:
            return firstNum.compareTo(secondNum) > 0;
        case GREATER_THAN_OR_EQUALS:
            return firstNum.compareTo(secondNum) >= 0;
    }

    throw new IllegalArgumentException("Will never reach here");
}

public enum Operator {
    LESS_THAN, LESS_THAN_OR_EQUALS, GREATER_THAN, GREATER_THAN_OR_EQUALS, EQUALS
}