java – 如何为包含双字段的类实现equals / hashCode方法
发布时间:2020-12-15 02:20:23 所属栏目:Java 来源:网络整理
导读:我在包含双字段的类中重写equals和hashCode.我的第一种方法是在equals方法中使用epsilon测试,在hashCode中使用Double.hashCode(double),但这会导致具有不同哈希码的相等对象;这是一个简化的例子: public class DoubleHashTest2{ public static void main(St
我在包含双字段的类中重写equals和hashCode.我的第一种方法是在equals方法中使用epsilon测试,在hashCode中使用Double.hashCode(double),但这会导致具有不同哈希码的相等对象;这是一个简化的例子:
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; } } } 我想过几个解决方案,包括转换为BigDecimal,但我对它们中的任何一个都不满意.我最终决定舍入: 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; } 但选择一个好的舍入算法很困难,而且这看起来很昂贵.我查看了类似的类,例如Point2D.Double,但是这个类中的equals失败,例如,当比较.8和0.7999999999999999时. 是否有推荐的方法来处理这个问题? 解决方法
回答主要问题
您不需要任何自定义舍入,因为Double类具有 此外,对于equals()方法,您可以将两个double值与 您的示例可能使用equals()和hashCode(): public boolean equals(Object other) { if (this == other) { return true; } if (null == other || this.getClass() != other.getClass()) { return false; } return Double.compare(this.dnum1,((Test) other).dnum1) == 0; } public int hashCode() { long bits = Double.doubleToLongBits(this.dnum1); return (int) (bits ^ (bits >>> 32)); } 关于浮点运算 您的示例显示了浮点计算的双重使用的缺点 – 即使具有相同幅度的值也可以给出接近但不同的结果.也许你应该使用BigDecimal? 另请参阅this question答案. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容