There was a problem when handling payment amount verification in the past two days. I used BigDecimal's equals method to compare whether the two amounts are equal, which resulted in an error in the amount comparison (such as the comparison between 3.0 and 3.00, etc.).
[Note: The following are all about sun jdk version 1.4.2 as an example. The implementation of other versions may not be consistent, please ignore it]
First, let’s take a look at BigDecimal’s equals method:
public boolean equals(Object x){if (!(x instanceof BigDecimal)) return false;BigDecimal xDec = (BigDecimal) x;return scale == xDec.scale && intVal.equals(xDec.intVal); }You can see that BigDecimal's euquals method is to first determine the data type to be compared. If the object types are consistent, it is determined at the same time whether the accuracy (scale) and value (BigInteger's equals method) are consistent.
In fact, it is already very clear in 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)." I just didn't pay attention!
Let's take a look at the compareTo method:
public int compareTo(BigDecimal val){/* Optimization: would run fine without the next three lines */int sigDiff = signum() - val.signum();if (sigDiff != 0) 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].intVal.compareTo(arg[1].intVal); } You can see that there is a matchScale processing in this method, which means converting the object with low accuracy to high accuracy, and then comparing it (also BigInteger's compareTo method). The implementation of matchScale is as follows:
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); } Do a simple test:
System.out.println(new BigDecimal("1.2").equals(new BigDecimal("1.20"))); //Output falseSystem.out.println(new BigDecimal("1.2").compareTo(new BigDecimal("1.20")) == 0); //Output true Also noticed that the BigDecimal constructor above is passed in strings. If the passed in number type, what will happen? You can test it yourself and analyze the reasons:
System.out.println(new BigDecimal("1.2").equals(new BigDecimal("1.20"))); //Output falseSystem.out.println(new BigDecimal("1.2").compareTo(new BigDecimal("1.20")) == 0); //Output true System.out.println(new BigDecimal(1.2).equals(new BigDecimal("1.20"))); //Output is it?System.out.println(new BigDecimal(1.2).compareTo(new BigDecimal("1.20")) == 0); //Is the output? System.out.println(new BigDecimal(1.2).equals(new BigDecimal(1.20))); //Is the output? System.out.println(new BigDecimal(1.2).compareTo(new BigDecimal(1.20)) == 0); //Is the output?The final conclusion is: for BigDecimal's size comparison, using the equals method will not only compare the size of the value, but also compare the accuracy of the two objects. The compareTo method will not compare the accuracy, but only compare the size of the value.
Finally, I despise myself. I have used Java language for so many years and I haven’t even figured out the basic common sense!
The above article briefly talks about the difference between BigDecimal's equals and compareTo in Java is all the content I share with you. I hope you can give you a reference and I hope you can support Wulin.com more.