Java 有理数的哈希代码
我在java中实现了一个类来建模有理数,它有两个整数来建模分子和分母。我需要重写Object的hashcode方法,因此相同的数字具有相同的hashcode 我定义了equals()方法,如下所示:Java 有理数的哈希代码,java,Java,我在java中实现了一个类来建模有理数,它有两个整数来建模分子和分母。我需要重写Object的hashcode方法,因此相同的数字具有相同的hashcode 我定义了equals()方法,如下所示: public boolean equals(Object obj) { Racional r = null; if (obj instanceof Racional) { r = (Racional) obj; } else { return
public boolean equals(Object obj) {
Racional r = null;
if (obj instanceof Racional) {
r = (Racional) obj;
} else {
return false;
}
return r.getDenominador() * this.numerador == r.getNumerador() * this.denominador;
}
关于这一点:
返回分子*分母是一个好方法吗
等价的有理数(如1/4和2/8)是否应该返回相同的哈希代码 建议如下:
37*numerator + 13* denominator
对于hashcode,其中这些是素数
我认为1/4和2/8是不同的,除非你有积极的正常化政策。但这取决于你。确保你能很好地记录这些行为
更新:
你需要决定什么是平等。我会先正常化,然后写:
return this.numerator == r.numerator && this.denominator == r.denominator
建议如下:
37*numerator + 13* denominator
对于hashcode,其中这些是素数
我认为1/4和2/8是不同的,除非你有积极的正常化政策。但这取决于你。确保你能很好地记录这些行为
更新:
你需要决定什么是平等。我会先正常化,然后写:
return this.numerator == r.numerator && this.denominator == r.denominator
这完全取决于您如何实现
equals
方法。如果obj1.equals(obj2)
为true
,obj1.hashCode()==obj2.hashCode()
也应为true
。我可能只会使用新的双精度((双精度)分子/分母).hashCode()
进行哈希运算,但您的要求可能不允许这样做
/编辑考虑到
equals
方法,对哈希使用分子*分母将是无效的方法。使用您的1/4
和2/8
示例,1/4.equals(2/8)
将返回true
,但1/4.hashCode()==2/8.hashCode()
将计算为4==16
,并返回false
,这一切取决于您如何实现equals
方法。如果obj1.equals(obj2)
为true
,obj1.hashCode()==obj2.hashCode()
也应为true
。我可能只会使用新的双精度((双精度)分子/分母).hashCode()
进行哈希运算,但您的要求可能不允许这样做
/编辑
考虑到equals
方法,对哈希使用分子*分母将是无效的方法。使用1/4
和2/8
的示例,1/4.equals(2/8)
将返回true
,但1/4.hashCode()==2/8.hashCode()
将计算为4==16
,并返回false
等价的有理数(如1/4和2/8)是否应该返回相同的哈希代码
由于您的equals()
方法为1/4和2/8返回true
实现这一点的一种方法是简化分数(例如,在构建时)。这可以通过将分子和分母除以它们的值来实现。一旦您这样做,任何合理的hashCode()
函数都会完成这项工作
等价的有理数(如1/4和2/8)是否应该返回相同的哈希代码
由于您的equals()
方法为1/4和2/8返回true
实现这一点的一种方法是简化分数(例如,在构建时)。这可以通过将分子和分母除以它们的值来实现。一旦执行此操作,任何合理的hashCode()
函数都可以完成此工作。在计算hashCode之前,您可以进行简化,这样即使对象的值为2/8,其hashCode的计算值为1/4Yes,但它不会给hashcode方法增加不必要的复杂性吗?@EugenioCuevas捕获本可以防止的异常通常被认为是错误的做法(抛出/捕获异常是一个耗时的操作)。通常建议在施法之前使用if(obj instanceof Racional)
,以防止ClassCastException
s.@Jeffrey你完全正确,谢谢@EugenioCuevas:复杂度是必要的还是不必要的,只有你才能知道。你可以在计算hashcode之前进行简化,这样即使对象的值是2/8,它的hashcode是用1/4Yes计算的,但它不会给hashcode方法增加不必要的复杂性吗?@EugenioCuevas捕获本可以防止的异常通常被认为是错误的做法(抛出/捕获异常是一个耗时的操作)。通常建议在施法之前使用if(obj instanceof Racional)
,以防止ClassCastException
s.@Jeffrey你完全正确,谢谢@EugenioCuevas:复杂性是必要的还是不必要的,只有你才能知道。我添加了我已经定义的equals方法,为什么hashcode方法依赖于它?@EugenioCuevas,因为这就是方法的定义方式。我尝试了你的解决方案,我所期望的唯一缺陷是获取无限或NaN值的哈希代码时出现异常或其他情况,但事实证明无限也有一个哈希代码,太完美了!谢谢我已经添加了我已经定义的equals方法,为什么hashcode方法依赖于它?@EugenioCuevas,因为这就是方法的定义方式。我尝试了你的解决方案,我所期望的唯一缺陷是获得无限或NaN值的hashcode时出现异常或其他情况,但事实证明infinite也有一个hashcode,太完美了!谢谢