# In AffineTransform, equals(Object) is inconsistent with hashCode()

XMLWordPrintable

#### Details

• Bug
• Resolution: Fixed
• P4
• 8, 11, 17
• b19
• generic
• generic

#### Description

A DESCRIPTION OF THE PROBLEM :
The equals(Object) method is inconsistent with hashCode() in the AffineTransform class. This bug prevents the use of AffineTransform as keys in HashMap, unless AffineTransform construction is well-controlled or some workaround is applied before any use as key.

More specifically, AffineTransform breaks two contracts documented in Object.equals(Object) javadoc:

* A.equals(A) returns false if at least one affine transform coefficient is NaN.
* A.equals(B) should imply A.hashCode() == B.hashCode(), but it is not the case if a coefficient is zero with an opposite sign in A and B.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Following code should print "true" but prints "false":

AffineTransform a = new AffineTransform(1, 0, 0, 1, Double.NaN, 0);
System.out.println(a.equals(a));

Following code should print either "true, true" or "false, <anything>" but print "true, false":

AffineTransform a = new AffineTransform(2, 0, 0, 3, 0, +0.0);
AffineTransform b = new AffineTransform(2, 0, 0, 3, 0, -0.0);
System.out.println(a.equals(b));
System.out.println(a.hashCode() == b.hashCode());

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
true
true
true

or

true
false
<anything>

ACTUAL -
false
true
false

---------- BEGIN SOURCE ----------
import java.awt.geom.AffineTransform;

public class Test {
public static void main(String[] args) {
AffineTransform r = new AffineTransform(1, 0, 0, 1, Double.NaN, 0);
System.out.println(r.equals(r));

AffineTransform a = new AffineTransform(2, 0, 0, 3, 0, +0.0);
AffineTransform b = new AffineTransform(2, 0, 0, 3, 0, -0.0);
System.out.println(a.equals(b));
System.out.println(a.hashCode() == b.hashCode());
}
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Before any use of AffineTransform as a key in an HashMap:

private static double pz(double value) {
return (value != 0) ? value : 0;
}

private static void fix(AffineTransform a) {
a.setTransform(
pz(a.getScaleX()), pz(a.getShearY()),
pz(s.getShearX()), pz(a.getScaleY()),
pz(a.getTranslateX()), pz(a.getTranslateY()));
}

FREQUENCY : always

#### People

Philip Race
Webbug Group