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
}

私の問題は、このSubscriberクラスのequal()メソッドとhashCode()メソッドをオーバーライドする必要があることです。equal()のオーバーライドはやや簡単な作業です(基本的な属性を比較するだけです。この場合は3つあります)。しかし、hashCode()メソッドをオーバーライドしているときに問題が発生します。ドメインを管理しながら、Hibernateが安全に使用できると信頼できるhashCode()を作成する方法。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 のような IDE を使用してhashCodeメソッドを生成できます。サンプルhashCodeメソッドの 1 つを以下に示します。

    @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 アプリケーションの実行中に同じオブジェクトに対して複数回呼び出された場合は常に、オブジェクトの equals 比較で使用される情報が変更されていない限り、hashCode メソッドは一貫して同じ整数を返す必要があります。この整数は、あるアプリケーションの実行から同じアプリケーションの別の実行まで一貫性を保つ必要はありません。

  • equals(Object) メソッドに従って 2 つのオブジェクトが等しい場合、2 つのオブジェクトのそれぞれで hashCode メソッドを呼び出すと、同じ整数結果が生成される必要があります。
  • equals(java.lang.Object) メソッドに従って 2 つのオブジェクトが等しくない場合、2 つのオブジェクトのそれぞれで hashCode メソッドを呼び出すと、異なる整数結果が生成される必要はありません。ただし、プログラマーは、等しくないオブジェクトに対して個別の整数結果を生成すると、ハッシュ テーブルのパフォーマンスが向上する可能性があることに注意する必要があります。

素数 31 を使用し、a*31^(x)+b*31^(x-1)+..c の属性値を組み合わせて、オブジェクトの一意の数を実現する一般的な方法です。hashCodeその過程で、下線オブジェクトのメソッドを使用できます。上記の方法も同様です。

于 2012-11-19T16:28:35.053 に答える
2

指定された 3 つの属性を使用して一意のハッシュ値を返す hashCode() を作成するにはどうすればよいですか?

一意である必要はありません。等しくない値を区別するのに十分なほど明確である必要があります。

一般的な方法の 1 つは、コンポーネント ハッシュ コードを使用し、それらを組み合わせること((h1*31)+h2)*31+h3です。

その方法は次のとおりです。まず、 を次のように定義hashCodeしますTopic

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

もオーバーライドする必要がありTopicますequals

Subscriber次に、次のように のハッシュ コードを定義します。

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

上記のコードは、コンストラクターが のすべてのコンポーネントをSubscriber非 null に初期化することを前提としています。

于 2012-11-19T16:28:27.250 に答える
1

hashCode()一意である必要はありません。唯一のことは、 。の場合、obj1とに対して同じハッシュコードを返さなければならないということです。たとえば、戻ることができます。obj2obj1.equals(obj2)email.hashCode()

完全なハッシュ関数は存在しません。異なる要素のペアごとに異なるハッシュコードを返すことはできません。Javaはequalsさらに差別化するために使用します(ハッシュコードが同じ場合)。

于 2012-11-19T16:27:15.027 に答える