0

我有一个名为的域类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
}

我的问题是我需要重写此订阅者类的 equal() 和 hashCode() 方法。覆盖 equal() 有点容易(只是比较基本属性,在这种情况下有三个)。但是我在覆盖 hashCode() 方法时遇到了问题。在管理我的域的同时,我如何编写我可以信任的 hashCode() 以供 hibernate 安全使用。我可以相信 IDE 生成的吗?

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

4

4 回答 4

6

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

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

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

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

于 2012-11-19T16:29:37.573 回答
4

您可以使用 Eclipse 之类的 IDEhashCode为您生成方法。一种示例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#hashCodeAPI:

hashCode 的一般合约是:

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

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

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

于 2012-11-19T16:28:35.053 回答
2

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

它不必是唯一的,只要足以区分不相等的值即可。

一种常见的方法是使用组件哈希码,并将它们组合起来((h1*31)+h2)*31+h3,依此类推。

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

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

您还需要覆盖Topic's equals

然后为 定义哈希码Subscriber,如下所示:

int hashCode() {
    return id.hashCode()*31*31*31
         + email.hashCode()*31*31
         + subscriberName.hashCode()*31
         + subscribingTopic.hashCode();
}

上面的代码假定构造函数将 的所有组件初始化Subscriber为非空。

于 2012-11-19T16:28:27.250 回答
1

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

完美的哈希函数不存在——不可能为每对不同的元素返回不同的哈希码。Javaequals用于进一步区分(如果哈希码相同)。

于 2012-11-19T16:27:15.027 回答