To be short:
firstBigDecimal.compareTo(secondBigDecimal) < 0 // "<"
firstBigDecimal.compareTo(secondBigDecimal) > 0 // ">"
firstBigDecimal.compareTo(secondBigDecimal) == 0 // "=="
firstBigDecimal.compareTo(secondBigDecimal) != 0 // "!="
firstBigDecimal.compareTo(secondBigDecimal) >= 0 // ">="
firstBigDecimal.compareTo(secondBigDecimal) <= 0 // "<="
Answer from torina on Stack OverflowVideos
To be short:
firstBigDecimal.compareTo(secondBigDecimal) < 0 // "<"
firstBigDecimal.compareTo(secondBigDecimal) > 0 // ">"
firstBigDecimal.compareTo(secondBigDecimal) == 0 // "=="
firstBigDecimal.compareTo(secondBigDecimal) != 0 // "!="
firstBigDecimal.compareTo(secondBigDecimal) >= 0 // ">="
firstBigDecimal.compareTo(secondBigDecimal) <= 0 // "<="
Every object of the Class BigDecimal has a method compareTo you can use to compare it to another BigDecimal. The result of compareTo is then compared > 0, == 0 or < 0 depending on what you need. Read the documentation and you will find out.
The operators ==, <, > and so on can only be used on primitive data types like int, long, double or their wrapper classes like Integerand Double.
From the documentation of compareTo:
Compares this
BigDecimalwith the specifiedBigDecimal.Two
BigDecimalobjects that are equal in value but have a different scale (like 2.0 and 2.00) are considered equal by this method. This method is provided in preference to individual methods for each of the six boolean comparison operators (<, ==, >, >=, !=, <=). The suggested idiom for performing these comparisons is:(x.compareTo(y) <op> 0), where<op>is one of the six comparison operators.Returns: -1, 0, or 1 as this BigDecimal is numerically less than, equal to, or greater than val.
The reason you have two different methods is that they do two different things.
The .equals method returns a boolean value indicating whether the object on which you call the method is equal to the object passed in as a parameter (for some definition of "is equal to" that is consistent with the nature of the object being compared).
The .compareTo method returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. That makes it a useful method for sorting; it allows you to compare one instance with another for purposes of ordering.
When the Java documentation says that these two methods must behave consistently, what they mean is that the .equals method must return true in exactly the same situations where the .compareTo method returns zero, and must return false in exactly the same situations where the .compareTo method returns a nonzero number.
Is there any good reason to violate these rules? Generally no, for the same reasons that
#define TRUE FALSE
is a really bad idea. The only legitimate reason for inconsistent behavior is hinted at in the Java documentation itself: "[if the] class has a natural ordering that is inconsistent with equals."
To drive home the point, you can actually define .equals() in terms of compareTo(), thus guaranteeing consistent behavior. Consider this .equals() method from a Rational class which, after a few sanity checks, simply defines .equals as compareTo() == 0:
public boolean equals(Object y) {
if (y == null) return false;
if (y.getClass() != this.getClass()) return false;
Rational b = (Rational) y;
return compareTo(b) == 0;
}
This confusion would occur in situations where there are conflicting understandings of equals.
compareTo is 'easy' in that it asks a simple question 'which one is bigger?' If you were given a bunch of Things, how do you sort them?
equals on the other hand wants to ask 'are these the same thing?'
BigDecimal in Java is one such place where there are conflicting understandings of what it means to have two things being equal.
BigDecimal foo = new BigDecimal("1.00");
BigDecimal bar = new BigDecimal("1.000");
These two entires will have the same meaning for sorting. They, however, are not the same when it comes to equality. They have a different underlying state (the precision of the number) and that means they are not equal but foo.compareTo(bar) will return 0.
Consider this, if you had a Map qux = HashMap<BigDecimal, Object>() for some reason, do you want qux.put(foo,foo) to take the same spot as qux.put(bar,bar) and thus evict the earlier insertion?
So, while they are math equals (which is how compareTo sorts them), they are not inner state equals, and thus the necessity of the inconsistency here.
Yes, this inconsistency comes at the price of a higher cognitive load for dealing with BigDecimal. It means maps may not behave like you want them to... and the question is "which map do you want to behave 'right'?"
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.TreeMap;
class Main {
public static void main (String[] args) {
BigDecimal foo = new BigDecimal("1.00");
BigDecimal bar = new BigDecimal("1.000");
HashMap<BigDecimal, String> hash = new HashMap();
TreeMap<BigDecimal, String> tree = new TreeMap();
hash.put(foo, "foo");
hash.put(bar, "bar");
tree.put(foo, "foo");
tree.put(bar, "bar");
System.out.println("hash foo: " + hash.get(foo));
System.out.println("hash bar: " + hash.get(bar));
System.out.println("tree foo: " + tree.get(foo));
System.out.println("tree bar: " + tree.get(bar));
}
}
ideone
Output:
hash foo: foo
hash bar: bar
tree foo: bar
tree bar: bar
Because compareTo returned 0, in the TreeMap, bar evicted foo when bar was inserted. However, because these are different objects with different internal state and thus different hash codes, they were both able to exist within a HashMap.
From the docs:
Note: care should be exercised if
BigDecimalobjects are used as keys in a SortedMap or elements in a SortedSet sinceBigDecimal's natural ordering is inconsistent with equals. See Comparable, SortedMap or SortedSet for more information.
And so, thats the problem, the inconsistency and the "there's no good answer to this" dilemma.
One could also imagine this with a Rational class where one wants to keep 2/4 having the internal state of 2/4 so that:
Rational twoFourths = new Rational(2,4);
Rational oneHalf = new Rational(1,2);
System.out.println(twoFourths); // prints 2/4
System.out.println(oneHalf); // prints 1/2
System.out.println(twoFourths.compareTo(oneHalf)); // prints 0
System.out.println(twoFourths.equals(oneHalf)); // ???
And you are once again up against that same question. Are these equal with the mathematical sense of equality (which means the hashCode needs to also return the same value?) or are they not equal using the object oriented state of the object sense of equality despite being the 'same'.