1. 概述
在日常的Java编程中,Integer
和 BigDecimal
是两种常用的数字类型。
在这个快速教程中,我们将探讨如何将一个 BigDecimal
数字乘以一个 Integer
数字。
2. 问题介绍
通过一个例子可以快速理解这个问题。假设我们有一个 BigDecimal
数字和一个整数:
final BigDecimal BIG = new BigDecimal("42.42");
final int INT = 10;
然后我们想计算 42.42 x 10
的结果,得到另一个 BigDecimal
数字:
final BigDecimal EXPECTED = new BigDecimal("424.2");
BigDecimal
提供了一套数学计算方法,如 add()
、divide()
、subtract()
和 multiply()
等,这些方法使我们能够方便地执行标准算术运算。然而,需要注意的是,这些方法只接受两个 BigDecimal
对象之间的计算,换句话说,它们只接受 BigDecimal
类型的参数。
因此,我们不能直接将 BigDecimal
与 Integer
相乘。
接下来,让我们看看如何进行计算。为了简单起见,我们将使用单元测试断言来验证解决方案是否产生预期的结果。
3. 将 Integer
转换为 BigDecimal
实例
现在我们知道 BigDecimal.multiply()
方法只接受 BigDecimal
数字作为参数。所以,如果我们可以将 Integer
对象转换为 BigDecimal
对象,我们就可以执行乘法运算。
BigDecimal
类提供了 valueOf()
方法,允许我们从 Integer
获取 BigDecimal
数字:
BigDecimal result = BIG.multiply(BigDecimal.valueOf(INT));
assertEquals(0, EXPECTED.compareTo(result));
运行测试后,它会通过。这样我们就得到了预期的结果。
值得一提的是,除了 BigDecimal.valueOf(INT)
方法,我们还可以使用构造函数 new BigDecimal(INT)
来从 Integer
获取 BigDecimal
数字。
然而,优先使用 valueOf()
方法。这是因为 BigDecimal
类预定义了从零到十的常用实例:
ZERO_THROUGH_TEN = new BigDecimal[]{new BigDecimal(BigInteger.ZERO, 0L, 0, 1),
new BigDecimal(BigInteger.ONE, 1L, 0, 1),
new BigDecimal(BigInteger.TWO, 2L, 0, 1),
new BigDecimal(BigInteger.valueOf(3L), 3L, 0, 1),
...
new BigDecimal(BigInteger.TEN, 10L, 0, 2)};
valueOf()
方法会检查给定的整数是否在“零到十”的范围内,并尝试重用预定义的实例。相反,调用构造函数始终会创建一个新的 BigDecimal
实例。
4. 关于断言的一点说明
我们已经编写了一个测试,并且它验证了解决方案有效。然而,细心的读者可能会注意到断言看起来有些奇怪:
assertEquals(0, EXPECTED.compareTo(result));
有些人可能想要简化它以提高可读性:
assertEquals(EXPECTED, result);
但是,如果我们运行带有上述断言的测试,测试会失败:
org.opentest4j.AssertionFailedError:
Expected :424.2
Actual :424.20
这是因为 BigDecimal
的 equals()
方法不仅比较两个 BigDecimal
数字的值,还会检查它们的小数位数(scale):
public boolean equals(Object x) {
if (x instanceof BigDecimal xDec) {
if (x == this) {
return true;
} else if (this.scale != xDec.scale) {
return false;
} else {
...
}
在我们的案例中,我们只关心 BigDecimal
数字的值。因此,我们需要调用 compareTo()
方法。
或者,我们可以使用 AssertJ 的 isEqualByComparingTo()
方法让代码更易读:
assertThat(result).isEqualByComparingTo(EXPECTED);
5. 总结
在这篇文章中,我们学习了如何将 BigDecimal
与 Integer
相乘。由于 BigDecimal.multiply()
只接受 BigDecimal
对象作为参数,所以在调用 multiply()
方法之前,我们需要将 Integer
对象转换为 BigDecimal
实例。
如往常一样,文章中展示的所有代码片段可在 GitHub 上找到。