为什么不能使用bigdecimal的equals比较大小

BigDecimal,相信对于很多人来说都不陌生,很多人都知道他的用法,这是一种 java.math 包中提供的一种可以用来进行精确运算的类型。

很多人都知道,在进行金额表示、金额计算等场景,不能使用 double、float 等类型,而是要使用对精度支持的更好的 BigDecimal。

所以,很多支付、电商、金融等业务中,BigDecimal 的使用非常频繁。而且不得不说这是一个非常好用的类,其内部自带了很多方法,如加,减,乘,除等运算方法都是可以直接调用的。

除了需要用 BigDecimal 表示数字和进行数字运算以外,代码中还经常需要对于数字进行相等判断。

关于这个知识点,在最新版的《阿里巴巴 Java 开发手册》中也有说明:

这背后的思考是什么呢?

我在之前的 CodeReview 中,看到过以下这样的低级错误:

 

if(bigDecimal == bigDecimal1){
    // 两个数相等
}

这种错误,相信聪明的读者一眼就可以看出问题,因为 BigDecimal 是对象,所以不能用 == 来判断两个数字的值是否相等。

以上这种问题,在有一定的经验之后,还是可以避免的,但是聪明的读者,看一下以下这行代码,你觉得他有问题吗:

可以明确的告诉大家,以上这种写法,可能得到的结果和你预想的不一样!

先来做个实验,运行以下代码:

BigDecimal bigDecimal = new BigDecimal(1);
BigDecimal bigDecimal1 = new BigDecimal(1);
System.out.println(bigDecimal.equals(bigDecimal1));

BigDecimal bigDecimal2 = new BigDecimal(1);
BigDecimal bigDecimal3 = new BigDecimal(1.0);
System.out.println(bigDecimal2.equals(bigDecimal3));

BigDecimal bigDecimal4 = new BigDecimal("1");
BigDecimal bigDecimal5 = new BigDecimal("1.0");
System.out.println(bigDecimal4.equals(bigDecimal5));

以上代码,输出结果为:

true
true
false

 BigDecimal 的 equals 原理

通过以上代码示例,我们发现,在使用 BigDecimal 的 equals 方法对 1 和 1.0 进行比较的时候,有的时候是 true(当使用 int、double 定义 BigDecimal 时),有的时候是 false(当使用 String 定义 BigDecimal 时)。

那么,为什么会出现这样的情况呢,我们先来看下 BigDecimal 的 equals 方法。

在 BigDecimal 的 JavaDoc 中其实已经解释了其中原因:

Compares this  BigDecimal with the specified Object for equality.  Unlike compareTo, this method considers two BigDecimal objects equal only if they are equal in value and scale (thus 2.0 is not equal to 2.00 when compared by  this method)

 大概意思就是,equals 方法和 compareTo 并不一样,equals 方法会比较两部分内容,分别是值(value)和标度(scale)

总结
BigDecimal 是一个非常好用的表示高精度数字的类,其中提供了很多丰富的方法。

但是,他的 equals 方法使用的时候需要谨慎,因为他在比较的时候,不仅比较两个数字的值,还会比较他们的标度,只要这两个因素有一个是不相等的,那么结果也是 false、

如果读者想要对两个 BigDecimal 的数值进行比较的话,可以使用 compareTo 方法。

备注:
在 Java 中,== 比较的是对象引用,而 equals 比较的是值。所以,在这个例子中,不同的对象有不同的引用,所以在进行比较的时候都将返回 false。奇怪的是,这里两个类似的 if 条件判断返回不同的布尔值。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿邱先森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值