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

Reply via email to