浅谈java中BigDecimal的equals与compareTo的区别
这两天在处理支付金额校验的时候出现了点问题,有个金额比较我用了BigDecimal的equals方法来比较两个金额是否相等,结果导致金额比较出现错误(比如3.0与3.00的比较等)。
【注:以下所讲都是以sunjdk1.4.2版本为例,其他版本实现未必一致,请忽略】
首先看一下BigDecimal的equals方法:
publicbooleanequals(Objectx){ if(!(xinstanceofBigDecimal)) returnfalse; BigDecimalxDec=(BigDecimal)x; returnscale==xDec.scale&&intVal.equals(xDec.intVal); }
可以看到BigDecimal的euquals方法是先判断要比较的数据类型,如果对象类型一致前提下同时判断精确度(scale)和值(BigInteger的equals方法)是否一致。
其实javadoc里面就已经写的很明白:“ComparesthisBigDecimalwiththespecifiedObjectforequality.UnlikecompareTo,thismethodconsiderstwoBigDecimalobjectsequalonlyiftheyareequalinvalueandscale(thus2.0isnotequalto2.00whencomparedbythismethod).”只是自己没有去注意罢了!
再看一下compareTo方法:
publicintcompareTo(BigDecimalval){ /*Optimization:wouldrunfinewithoutthenextthreelines*/ intsigDiff=signum()-val.signum(); if(sigDiff!=0) return(sigDiff>0?1:-1); /*Ifsignsmatch,scaleandcompareintVals*/ BigDecimalarg[]=newBigDecimal[2]; arg[0]=this; arg[1]=val; matchScale(arg); returnarg[0].intVal.compareTo(arg[1].intVal); }
可以看到这个方法里面有个matchScale的处理,意思是把精确度低的那个对象转换为高精确度,然后再进行比较(同样是BigInteger的compareTo方法),matchScale的实现如下:
privatestaticvoidmatchScale(BigDecimal[]val){ if(val[0].scale<val[1].scale) val[0]=val[0].setScale(val[1].scale); elseif(val[1].scale<val[0].scale) val[1]=val[1].setScale(val[0].scale); }
做个简单测试:
System.out.println(newBigDecimal("1.2").equals(newBigDecimal("1.20")));//输出false System.out.println(newBigDecimal("1.2").compareTo(newBigDecimal("1.20"))==0);//输出true
另外注意到我上面BigDecimal的构造方法里面传入的都是字符串,如果传入的是数字类型的话会有什么结果,大家可以自己测试一下,然后分析一下原因:
System.out.println(newBigDecimal("1.2").equals(newBigDecimal("1.20")));//输出false System.out.println(newBigDecimal("1.2").compareTo(newBigDecimal("1.20"))==0);//输出true System.out.println(newBigDecimal(1.2).equals(newBigDecimal("1.20")));//输出是? System.out.println(newBigDecimal(1.2).compareTo(newBigDecimal("1.20"))==0);//输出是? System.out.println(newBigDecimal(1.2).equals(newBigDecimal(1.20)));//输出是? System.out.println(newBigDecimal(1.2).compareTo(newBigDecimal(1.20))==0);//输出是?
最后结论是:对于BigDecimal的大小比较,用equals方法的话会不仅会比较值的大小,还会比较两个对象的精确度,而compareTo方法则不会比较精确度,只比较数值的大小。
最后鄙视一下自己,用了这么多年的Java语言,连基本的常识都没搞清楚!
以上这篇浅谈java中BigDecimal的equals与compareTo的区别就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。