I am overriding equals and hashCode in a class that includes double fields. My first approach was to use the epsilon test in the equals method, and Double.hashCode( double ) in hashCode, but that can result in equal objects having different hash codes; here is a simplified example:
public class DoubleHashTest2
{
public static void main(String[] args)
{
double base1 = .9;
double base2 = .7;
Test test1 = new Test( base1 - .1 );
Test test2 = new Test( base2 + .1 );
System.out.println( test1.equals( test2 ) );
System.out.println( test1.hashCode() );
System.out.println( test2.hashCode() );
}
private static class Test
{
private double dnum1;
public Test( double dnum1 )
{
this.dnum1 = dnum1;
}
public boolean equals( Test other )
{
final double epsilon = .0001;
boolean result = false;
if ( this == other )
result = true;
else if ( other == null )
result = false;
else
result = Math.abs( this.dnum1 - other.dnum1 ) < epsilon;
return result;
}
public int hashCode()
{
int hash = Double.hashCode( dnum1 );
return hash;
}
}
}
I've thought of several solutions, including converting to BigDecimal, but I'm not really happy with any of them. I finally settled on rounding:
public boolean equals( Test other )
{
boolean result = false;
if ( this == other )
result = true;
else if ( other == null )
result = false;
else
{
double test1 = round( dnum1 );
double test2 = round( other.dnum1 );
result = test1 == test2;
}
return result;
}
public int hashCode()
{
double temp = round( dnum1 );
int hash = Double.hashCode( temp );
return hash;
}
private double round( double dnum )
{
// tests for NaN and +/-infinity omitted for brevity
final int places = 4;
final double round_const = Math.pow( 10, places );
double result = ((int)(dnum * round_const + .5)) / round_const;
return result;
}
But choosing a good rounding algorithm is difficult, and this seems kind of expensive. I looked at similar classes, such as Point2D.Double, but equals in this class fails, for example, when comparing .8 and 0.7999999999999999.
Is there a recommended way for dealing with this issue?