2012-03-09 14 views
2

ですが、標準のメタアルゴリズムまたは他のクラスで構成されているクラスのためのhashCode()メソッドを実装する方法のベストプラクティス:我々はBとCはいくつかを置くと仮定した場合のhashCodeおよび集約

class A { B b; C c; ... } 

hashCode()を実装する際の努力のために、AのハッシュコードをBCのベースにすることは確かに良い考えです。しかし、どのように組み合わせるのがベスト?

特定の操作がで似明らかにあまり適していないので、私はこれを頼む:これは、2つの等しいBオブジェクトを持つように起こるすべてのナイーブなオブジェクトのための0のハッシュコードを引き起こす

class Naive { 
    B b1, b2; 
    public int hashCode() { return b1.hashCode()^b2.hashCode(); } 
} 

答えて

3

nwinklerのアルゴリズムは、(としてジョシュア・ブロックが効果的なJavaで記述するものに似ていますPuceの答えで参照される)。

考えられるのは、重要なフィールドに対して計算されたハッシュコードを組み合わせることです。奇数31の使用は、乗算のjvm最適化(シフト+減算)をもたらすことができる。 で、このハッシュコード計算からequals()で使用されていないフィールドを除外する必要があります。 は、計算に含まれるフィールドから値が計算されるフィールドを除外します。

Objectフィールドの推奨されるハッシュコード計算では、nullでない場合(0の場合)、オブジェクトのequals()メソッド自体がequals()で再帰的に呼び出される場合、hashcodeメソッドを再帰的に呼び出すだけです。方法。後者が当てはまらない場合(オブジェクトフィールドでより複雑な比較が行われる場合)、標準的な表現を作成し、それに対するハッシュコードを計算することをお勧めします。プリミティブフィールドのハッシュコードを計算するために

、以下のような方法が提案されている(彼らはまだ結果=結果*プライム+ fieldHashCodeを実行して結果に結合しなければならないことに注意してください):

  • フロート:Float.floatToIntBits(f)
  • int型、バイト、文字、短い:(int) f
  • 長い=>(int) (f^(f>>>32))
  • ブール:(f?1:0)
  • ダブル:longHash= Double.doubleToLongBits(f)次に、(int) (longHash^(longHash>>>32))
  • の配列を使用します。java 1.5では、いくつかのhashCodeメソッドがArraysクラスに導入されています。まるでフィールドのように、配列の要素に対して以前の規則を再帰的に適用することもできます。
5

これは、いくつかのEclipseプラグインを一般的なパターンであり、生成することができている:

@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + ((b1 == null) ? 0 : b1.hashCode()); 
    result = prime * result + ((b2 == null) ? 0 : b2.hashCode()); 
    // repeat for other attributes you want to include... 

    return result; 
} 

はそれに応じてequals()メソッドをコーディングすることを忘れないでください...

2

項8」のジョシュアブロッホ効果的なJavaの」本は良いアルゴリズムを示しています

http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf

は、Java SE 7を使用している場合は、UもできますSE:(ハッシュコードを生成します>ソースを使用した場合のEclipseによって生成されるもの、実際にあると等しい...機能)

http://docs.oracle.com/javase/7/docs/api/java/util/Objects.html#hash%28java.lang.Object...%29

+0

書籍の章全体にリンクを投稿するだけでなく、アルゴリズム自体を投稿することはできますか? –

+1

申し訳ありませんが、時間がありません。私は正しい方向を示すだけで十分だと思うし、他のソースをコピーする必要はありません。 – Puce

+0

@Puce - 大丈夫です、私はPDFを読むのが大好きです。ちょうどこの特定の主題のために始めるべき場所を本当に知らなかった。それで、あなたは本当に役に立ちます。 – Ingo

関連する問題