web-dev-qa-db-ja.com

hashCode()メソッドの作成-Java

作成したクラスのhashCode()メソッドの記述に問題があります。このクラスはTreeSet内で使用するためのものであり、Comparableを実装しています。クラスには次の変数があります。

_public class Node implements Comparable<Node> {
   Matrix matrix;
   int[] coordinates= new int[2];
   Node father;
   int depth;
   int cost;
_

これがcompareTo()メソッドの実装です。 TreeSetにこれらのNode構造をコストで編成してもらいたいため、compareTo()は単純な減算の結果を返します。

_public int compareTo(Node nodeToCompare) {
    return this.cost - nodeToCompare.cost;
}
_

equals()メソッドも実装しました。

_public boolean equals(Object objectToCompare) {
    if(objectToCompare== this) {return true;}
    if(objectToCompare== null || objectToCompare.getClass()!= this.getClass()) {return false;}

    Node objectNode= (Node) objectToCompare;
    return this.father.equals(objectNode.father) &&
            this.depth== objectNode.depth &&
            this.cost== objectNode.cost &&
            this.matrix.equals(objectNode.matrix) &&
            Arrays.equals(this.coordinates, objectNode.coordinates);
}
_

以上をすべて説明したので、いくつか質問があります。

  1. 新しいequals()メソッドを実装したので、新しいhashCode()メソッドを実装する必要がありますか?
  2. これらの変数で新しいhashCode method()を実装するにはどうすればよいですか? (タイプMatrixの変数マトリックスにはhashCode()メソッドが実装されていることに注意してください)

それで全部です!

18

Intellij IDEAは、これを「右クリック」機能として実行できます。正しく実行されていることを確認するだけで、多くのことがわかります。

そして、いずれの場合も両方をオーバーライドする必要があります。

8
sethcall

HashCodeメソッドの規約では、2つのオブジェクトが等しい場合、hashCode()を呼び出すと同じ整数の結果が得られることが示されています。逆は真である必要はありません。つまり、2つのhashCodeが同じである場合、オブジェクトは互いに等しい必要はありません。

Equalsメソッド(変数変換btwが必要)を見ると、equalsメソッドがtrueになるために等しい必要があるすべての内部メンバー変数のハッシュコードを追加できます。例えば.

public int hashCode() {
    return this.matrix.hashCode() + 
           this.coordinates[0] + 
           this.coordinates[1] + 
           this.father.hashCode() +
           this.depth + this.cost;               
}

上記では、行列と親がnullになることはないと想定しています。そうでない場合はnullをチェックする必要があります。

もっと冒険したい場合は、上記のいくつかに素数を掛けて、異なるデータに対してhashCodeの衝突が発生しないようにすることができます(これは、hashTablesとhashMapsでクラスを使用している場合のパフォーマンスの向上に役立ちます)。 nullに対応する必要がある場合は、上記のメソッドを次のように少し上手に書くことができます。

public int hashCode() {
    return ((this.matrix == null) ? 0 : this.matrix.hashCode()) + 
           17 * this.coordinates[0] + 
           this.coordinates[1] + 
           ((this.father == null) ? 0 : this.father.hashCode()) +
           31 * this.depth + 19 * this.cost;               
}
3
ksymeon

コレクションが小さい場合は、hashCodeメソッドから定数を返すことができます。迅速な検索に使用します。 hashCodesは要素を保持するボックスのようなものです。ルールは次のとおりです。

  1. 等しい要素は同じボックスになければなりません(同じhashCodeを持っています)-確かに;
  2. 等しくない要素は、同じボックス内または異なるボックス内にあります。

次に、定数を返し、これらの2つの規則に従いますが、小さいリストではパフォーマンスを大幅に低下させる可能性があります(JVMはすべての要素を検索し、同じボックス内の要素のみを検索しないため)。しかし、定数を返すのは悪いアプローチです。

PS:私の執筆のために申し訳ありません。英語は私の母国語ではありません。

PPS:通常、equalsと同じ方法でhashCodeメソッドを実装する必要があります(同じ要素を使用)

0
MikhailSP