浅谈java中BigDecimal的equals与compareTo的区别
这两天在处理⽀付⾦额校验的时候出现了点问题,有个⾦额⽐较我⽤了BigDecimal的equals⽅法来⽐较两个⾦额是否相等,结果导致⾦额⽐较出现错误(⽐如3.0与3.00的⽐较等)。
【注:以下所讲都是以sun jdk 1.4.2版本为例,其他版本实现未必⼀致,请忽略】
⾸先看⼀下BigDecimal的equals⽅法:
public boolean equals(Object x){
if (!(x instanceof BigDecimal))
return false;
BigDecimal xDec = (BigDecimal) x;
return scale == xDec.scale && intVal.equals(xDec.intVal);
}
可以看到BigDecimal的euquals⽅法是先判断要⽐较的数据类型,如果对象类型⼀致前提下同时判断精确度(scale)和值(BigInteger的equals⽅法)是否⼀致。
其实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).”只是⾃⼰没有去注意罢了!
再看⼀下compareTo⽅法:
public int compareTo(BigDecimal val){
/* Optimization: would run fine without the next three lines */
int sigDiff = signum() - val.signum();
if (sigDiff != 0)equals()方法
return (sigDiff > 0 ? 1 : -1);
/* If signs match, scale and compare intVals */
BigDecimal arg[] = new BigDecimal[2];
arg[0] = this; arg[1] = val;
matchScale(arg);
return arg[0].intValpareTo(arg[1].intVal);
}
可以看到这个⽅法⾥⾯有个matchScale的处理,意思是把精确度低的那个对象转换为⾼精确度,然后再进⾏⽐较(同样是BigInteger的compareTo⽅法),matchScale的实现如下:
private static void matchScale(BigDecimal[] val) {
if (val[0].scale < val[1].scale)
val[0] = val[0].setScale(val[1].scale);
else if (val[1].scale < val[0].scale)
val[1] = val[1].setScale(val[0].scale);
}
做个简单测试:
System.out.println(new BigDecimal("1.2").equals(new BigDecimal("1.20"))); //输出false
System.out.println(new BigDecimal("1.2")pareTo(new BigDecimal("1.20")) == 0); //输出true
另外注意到我上⾯BigDecimal的构造⽅法⾥⾯传⼊的都是字符串,如果传⼊的是数字类型的话会有什么结果,⼤家可以⾃⼰测试⼀下,然后分析⼀下原因:
System.out.println(new BigDecimal("1.2").equals(new BigDecimal("1.20"))); //输出false
System.out.println(new BigDecimal("1.2")pareTo(new BigDecimal("1.20")) == 0); //输出true
System.out.println(new BigDecimal(1.2).equals(new BigDecimal("1.20"))); //输出是?
System.out.println(new BigDecimal(1.2)pareTo(new BigDecimal("1.20")) == 0); //输出是?
System.out.println(new BigDecimal(1.2).equals(new BigDecimal(1.20))); //输出是?
System.out.println(new BigDecimal(1.2)pareTo(new BigDecimal(1.20)) == 0);//输出是?
最后结论是:对于BigDecimal的⼤⼩⽐较,⽤equals⽅法的话会不仅会⽐较值的⼤⼩,还会⽐较两个对象的精确度,⽽compareTo⽅法则不会⽐较精确度,只⽐较数值的⼤⼩。
最后鄙视⼀下⾃⼰,⽤了这么多年的Java语⾔,连基本的常识都没搞清楚!
以上这篇浅谈java中BigDecimal的equals与compareTo的区别就是⼩编分享给⼤家的全部内容了,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论