2

簡単な質問です。私はオブジェクトを持っています:

class User {

    int id;
    String username;

    public User() {
    }

    public User(int id, String username) {
        this.id = id;
        this.username = username;
    }

    @Override
    public String toString() {
        return id + " - " + username;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 31 * hash + this.id;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final User other = (User) obj;
        return this.id == other.id;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public int getId() {
        return id;
    }
}

int id誰が等しいかは(データベース ID) に基づいて決定されます。

Netbeans はこのメソッドを自動生成しましたhashCode():

@Override
public int hashCode() {
    int hash = 7;
    hash = 31 * hash + this.id;
    return hash;
}

問題は、(すでに) unique を返すだけでこれに利点はありますint idか?

@Override
public int hashCode() {
    return id;
}

どちらにしても衝突はありえません。

右?

4

3 に答える 3

1

1) 次のことができます。

@Override
public int hashCode() {
    return 1; // or any int constant here
}


2) DBにそのようなオブジェクトが1,000,000あるとしたら、次のようなことができます:

@Override
public int hashCode() {
    return id % 10000;
}

このようにして、1,000,000 個のオブジェクトに対して 10,000 個のバケットが作成されます。

3) に変わっidて、Integerこれを行うだけです。

@Override
public int hashCode() {
    return id.hashCode();
}

または同等のものは次のとおりです。

@Override
public int hashCode() {
    return id;
}

1) と 3) は、hashCode 実装の境界ケースです。
アプローチ 2) はその中間です。

于 2014-03-31T21:32:37.790 に答える
1

Object.hashCode() javadocには、質問に答えるために知っておくべきことがすべて記載されています。

hashCode の一般的な契約は次のとおりです。

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

  • equals(Object) メソッドに従って 2 つのオブジェクトが等しい場合、2 つのオブジェクトのそれぞれで hashCode メソッドを呼び出すと、同じ整数結果が生成される必要があります。

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

于 2014-03-31T21:33:09.987 に答える
0

idと の間には全単射がある31 * 7 + idため、代わりに返すidことは同等です。したがって、return id;不要な計算/複雑さを単純に削除します。

しかし、それは準拠したハッシュコード方式を構成するでしょうか? javadoc に戻りましょう。

hashCode の一般的な契約は次のとおりです。

  • Java アプリケーションの実行中に同じオブジェクトに対して複数回呼び出された場合は常に、オブジェクトの equals 比較で使用される情報が変更されていない限り、hashCode メソッドは一貫して同じ整数を返す必要があります。この整数は、あるアプリケーションの実行から同じアプリケーションの別の実行まで一貫性を保つ必要はありません。
  • equals(Object) メソッドに従って 2 つのオブジェクトが等しい場合、2 つのオブジェクトのそれぞれで hashCode メソッドを呼び出すと、同じ整数結果が生成される必要があります。
  • equals(java.lang.Object) メソッドに従って 2 つのオブジェクトが等しくない場合、2 つのオブジェクトのそれぞれで hashCode メソッドを呼び出すと、異なる整数結果が生成される必要はありません。ただし、プログラマーは、等しくないオブジェクトに対して個別の整数結果を生成すると、ハッシュ テーブルのパフォーマンスが向上する可能性があることに注意する必要があります。

あなたの場合はうまくいきますか?

  • (i) うまくいけば満足です: 特定のオブジェクトの id を任意に変更することはありませんよね?
  • (ii)2人のユーザーが等しい場合、それらは同じハッシュコードを持っています:はい、あなたの等しいものもIDに基づいているためです
  • (iii) 満足している
于 2014-03-31T21:33:10.197 に答える