Double: equals doesn’t use Double.compare for field foo
You should never use ==
to compare doubles or floats in an equals
method. Always use Double.compare
or Double.compareTo
instead.
Josh Bloch explains this in his book Effective Java. The short summary is that this method will do the right thing when confronted with NaN
and positive and negative infinities. For example, Float.NaN
is not equal to itself, but it has to be for equals
, or you would never be able to retrieve it from a HashMap
.
Should you use a delta function, such as Math.abs(this.d - that.d) <= 0.0000001
to compare the values? In general, when comparing doubles, one should definitely do that, to avoid issues concerning rounding errors. In the case of equals
, however, you will run into transitivity issues:
According the the transitivity requirement of equals
, if a.equals(b)
and b.equals(c)
, a.equals(c)
should also be true, which isn’t the case when comparing deltas like this.
You will run into a similar problem when defining hashCodes
: if two objects are equal to each other, their hashCode
s must be equal as well. The only way to make this work, is to return a constant hashCode
, which is undesirable.
Therefore, while you should in principle always compare doubles using a delta function, equals
methods are an exception to this, and you should stick to using Double.compare
.