0

任意の型 (アトミック型) の複数列の主キーのハッシュ コードを生成するための一般的な衝突のない Java のベスト プラクティスは何ですか?

私はそれについて数時間考え、すべての主キー列で連結された文字列がそうする唯一の信頼できる方法であるという結論に達しました。次に、その連結された文字列で Java の hashCode メソッドを呼び出すと、一意の整数が生成されます。(実際には、データベースのインデックスが行うことを何らかの形で模倣しますが、ここではわかりません)

フォームの複数列の主キーの場合

CREATE TABLE PlayerStats
(
    game_id INTEGER,
    is_home BOOLEAN,
    player_id SMALLINT,
    roster_id SMALLINT,
    ... -- (game_id, is_home) FK to score, (player_id, roster_id) FK to team member
    PRIMARY KEY (game_id, is_home, player_id, roster_id)
)

ハッシュコードは次のように計算できます。

@Override
public int hashCode()
{
    //                                                                 maxchars:
    String surrogate =   String.format("%011d", this.gameId)         //11
                       + String.format("%01d" , this.isHome ? 1 : 0) //1
                       + String.format("%011d", this.playerId)       //6
                       + String.format("%011d", this.rosterId)       //6

    System.out.println("surrogate = '" + surrogate + "'");

    return surrogate.hashCode();
}

もちろん、equals もこれに基づいている場合、これは HashSets と Hashtable でのみ機能します。

私の質問: これは良い一般的な戦略ですか?

オンザフライ計算が最速ではない可能性があることがわかります。複合キーの値が変更されるたびに、ハッシュ コードを再計算したい場合があります (たとえば、キー プロパティで動作するすべてのセッター内から rehash() メソッドを呼び出します)。

提案と改善を歓迎します。これに対する一般的に知られている戦略はありませんか?パターン?

4

1 に答える 1

0

ハッシュコードは、同じコードを持つデータセット内の要素を検索するためのインデックスとして使用されます。次に、equalsメソッドを使用して、同じハッシュコードを持つ要素のセット内で一致するものを検索します。そのため、生成されたハッシュコードは100%一意である必要はありません。同じhashCode値を持つ多数のアイテムでequalsメソッドを呼び出す必要がないように、データ要素間に適切な分布を作成するには「十分に一意」である必要があります。

その観点から、たくさんの文字列を生成し、それらの文字列でハッシュコードを計算することは、3つの整数と1つのブール値の比較で構成されるequals操作を回避するための費用のかかる方法のように思えます。また、ハッシュコード値の一意性を必ずしも保証するものではありません。

私の推奨は、キーのハッシュコードをその構成要素のハッシュコードの合計にするという単純なアプローチから始めることです。すべてのIDが同様の範囲にあるためにそれが適切な分布を提供しない場合は、合計する前にIDにいくつかの異なる係数を掛けてみることができます。

于 2010-07-23T22:56:05.377 に答える