覆盖Java中的域类的equals()和hashCode()方法

时间:2012-11-19 16:25:17

标签: java hibernate java-ee hashcode

我有一个名为Subscriber的域类,其定义如下:

public class Subscriber {
   private long id;
   private String email;
   private String subscriberName;
   private Topic subscribingTopic;

   //other attributes and getters setters.
}

public class Topic{
   private long id;
   private String topicName; //unique
}

我的问题是我需要覆盖此Subscriber类的equal()和hashCode()方法。 覆盖equal()是一项简单的任务(只是比较基本属性,在这种情况下有三个)。但是我在覆盖hashCode()方法时遇到了问题。我如何编写hashCode(),我可以信任安全地使用hibernate,同时管理我的域。我可以信任IDE生成的吗?

任何帮助将不胜感激,并提前致谢!

4 个答案:

答案 0 :(得分:6)

如果您使用的是Java 7,则可以使用Objects.hash()

return Objects.hash(email, subscriberName, subscribingTopic);

如果您使用的是Java 6,则可以使用Guava的Objects.hashCode()方法(与上面相同)。

如果您使用的是Java 5,则可以使用Apache commons-lang HashCodeBuilder类来帮助您。

答案 1 :(得分:4)

您可以使用Eclipse之类的IDE为您生成hashCode方法。下面是一个示例hashCode方法:

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((email == null) ? 0 : email.hashCode());
        result = prime * result + (int) (id ^ (id >>> 32));
        result = prime
                * result
                + ((subscriberName == null) ? 0 : subscriberName.hashCode());
        result = prime
                * result
                + ((subscribingTopic == null) ? 0 : subscribingTopic
                        .hashCode());
        return result;
    }

您还需要在hashCode课程中创建类似的Topic方法。

Object#hashCode API:

  

hashCode的一般合约是:

     

每当在执行Java应用程序期间多次在同一对象上调用它时,hashCode方法必须始终返回相同的整数,前提是不修改对象的equals比较中使用的信息。从应用程序的一次执行到同一应用程序的另一次执行,此整数不需要保持一致。

     
      
  • 如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须生成相同的整数结果。
  •   
  • 如果两个对象根据equals(java.lang.Object)方法不相等,则不需要在两个对象中的每一个上调用hashCode方法必须生成不同的整数结果。但是,程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能。
  •   

它的一般做法是使用素数31并将属性值组合在一个* 31 ^(x)+ b * 31 ^(x-1)+ .. c中,以实现对象的唯一编号。在此过程中,您可以使用下划线对象的hashCode方法。上述方法也是如此。

答案 2 :(得分:2)

  

如何编写使用指定的三个属性返回唯一哈希值的hashCode()?

它不必是唯一的,只能区分不同的值。

一种常见的方法是使用组件哈希码,并将它们组合为((h1*31)+h2)*31+h3等等。

以下是您的操作方法:首先,为hashCode定义Topic,如下所示:

int hashCode() {
    return topicName.hashCode()*31 + (int)id;
}

您还需要覆盖Topic的{​​{1}}!

然后定义equals的哈希码,如下所示:

Subscriber

上面的代码假定构造函数将int hashCode() { return id.hashCode()*31*31*31 + email.hashCode()*31*31 + subscriberName.hashCode()*31 + subscribingTopic.hashCode(); } 的所有组件初始化为非null。

答案 3 :(得分:1)

hashCode()不一定是唯一的。唯一的问题是它必须返回obj1obj2的相同哈希码,如果obj1.equals(obj2)。例如,您可以返回email.hashCode()

不存在完美散列函数 - 不可能为每对不同元素返回不同的散列码。 Java使用equals进一步区分(如果哈希码相同)。