Eclipse自动生成的hashCode覆盖

时间:2013-07-17 23:28:14

标签: java

我使用eclipse来生成对象的hashCode和equals方法的覆盖,并生成了一些关于hashCode覆盖的问题。以下hashCode()是否正确?

问题:

- 为什么eclipse会生成两行 result = 代码行?我认为将两个结果加在一起是合适的。任何想法为什么他们是单独的任务?

- 最终的int prime是否为任何素数?

- int结果总是1?

public class Overrider {
    private Long id;
    private String name;
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Overrider other = (Overrider) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}

3 个答案:

答案 0 :(得分:1)

  

- 为什么eclipse会产生两个结果=代码行?我认为将两个结果加在一起是合适的。任何想法为什么   他们是单独的任务?

请记住,这是在eclipse中运行以生成代码的代码。因此,有一个特定的逻辑。 每个变量生成一行而不是一行生成一行要容易得多。

此外,它使代码更具可读性......您能想象将这两个语句合并为一个吗?

return prime * (prime + ((id == null) ? 0 : id.hashCode()) ) + 
((name == null) ? 0 : name.hashCode());

我不打算简化它,但如果有10个类变量,它会变得非常大而且可怕......

  

“最终的int prime可以是任何素数吗?”

看看:Why does Java's hashCode() in String use 31 as a multiplier? 我引用那里引用了“有效Java”一书......

  

根据约书亚布洛赫的有效Java(一本不可能的书)   建议不够,我买了,这要归功于不断的提及   计算器):

     

“选择值31是因为它是一个奇数素数。如果它是偶数   并且乘法溢出,信息将丢失,如   乘以2相当于移位。使用的好处   素数不太清楚,但它是传统的。 31的不错的财产是   乘法可以用移位和减法代替   为了更好的性能:31 * i ==(i <&lt; 5) - i。现代VM执行此操作   自动进行优化。“

答案 1 :(得分:1)

- 为什么eclipse会产生两个结果=代码行?我认为将两个结果加在一起是合适的。任何想法为什么他们是单独的任务? 答案:您已修复上面定义的'final int prime = 31;'。 假设以下情况

id.hashcode()= 1&amp; name.hashcode()= 2。 Hashcode by addition = 32 + 33 = 65 Hashcode with eclipse Implementation = 994

id.hashcode()= 2&amp; name.hashcode()= 1。 Hashcode by addition = 33 + 32 = 65 Hashcode with eclipse Implementation = 1024

Hashcode应尽可能独特,以获得更好的性能。添加结果后,可能有2个不同的对象返回相同的哈希码。而乘法,对不同对象的重复哈希码的可能性非常小。

- 最终的int prime是任何素数吗? 它可以是任何数字,但它确保不同对象的重复哈希码可能性更小。例如,上面表示即使两个不同对象的id.hashcodes中的1的差异将确保这两个对象的实际哈希码在至少31之间不同.S

- int结果总是1? 它可以是任何东西。只是它应该是非零的,并且应该避免计算的复杂性,以使其快速工作。

答案 2 :(得分:1)

对我来说很好。

  

“为什么eclipse会产生两个结果=代码行?”

我猜的原因是可读性。看起来你再次将第一个结果+第二个字段的哈希乘以素数,而不仅仅是将两个线加在一起。生成的代码看起来好多了:

result = (prime * result + ((id == null) ? 0 : id.hashCode())) + 
         (prime * (prime * result + ((id == null) ? 0 : id.hashCode())) + 
         ((name == null) ? 0 : name.hashCode())); 
  

“最终的int prime可以是任何素数吗?”

是的,但越高越好。数字越大,发生碰撞的可能性越小。在大多数情况下,31应该绰绰有余。

  

“int int结果总是1?”

假设您的意思是“应该将int结果始终初始化为1”:

不,它只需要一些不为0的常量。