java.awt.geom.AffineTransform.hashCode() is inconsistent with equals(Object)
Martin Desruisseaux
martin.desruisseaux at geomatys.fr
Fri May 20 15:56:43 UTC 2011
Hello all
I realize that this is a Java2D bug, but given that it is a simple
equals(Object)/hashCode() implementation issue maybe this list is still relevant...
AffineTransform.hashCode() method is inconsistent with equals(Object) when some
'double' values are 0.0 values of opposite sign. The reason is that 'hashCode()'
uses 'doubleToLongBits(double)' which return different values for positive and
negative zero, while 'equals(Object)' uses '==' which treat -0.0 as equals to
+0.0. I verified in latest JDK 7 source code that this bug is still present.
Trivial test case:
import java.awt.geom.AffineTransform;
public class AffineBug {
public static void main(String[] args) {
AffineTransform tr1 = new AffineTransform();
AffineTransform tr2 = new AffineTransform();
tr2.translate(-0.0, 0);
System.out.println("hashCode 1: " + tr1.hashCode());
System.out.println("hashCode 2: " + tr2.hashCode());
System.out.println("equals: " + tr1.equals(tr2));
}
}
Current AffineTransform.equals(Object) implementation is:
public boolean equals(Object obj) {
if (!(obj instanceof AffineTransform)) {
return false;
}
AffineTransform a = (AffineTransform)obj;
return ((m00 == a.m00) && (m01 == a.m01) && (m02 == a.m02) &&
(m10 == a.m10) && (m11 == a.m11) && (m12 == a.m12));
}
Possible fix would be (assuming appropriate static import):
public boolean equals(Object obj) {
if (!(obj instanceof AffineTransform)) {
return false;
}
AffineTransform a = (AffineTransform)obj;
return ((doubleToLongBits(m00) == doubleToLongBits(a.m00))
&& (doubleToLongBits(m01) == doubleToLongBits(a.m01))
&& (doubleToLongBits(m02) == doubleToLongBits(a.m02))
&& (doubleToLongBits(m10) == doubleToLongBits(a.m10))
&& (doubleToLongBits(m11) == doubleToLongBits(a.m11))
&& (doubleToLongBits(m12) == doubleToLongBits(a.m12)));
}
Note that this have the side effect of considering NaN values as equal.
Similar bug affect also Point2D and Rectangle2D (I did not checked the other
geometric classes).
Regards,
Martin
More information about the core-libs-dev
mailing list