3

次の 2 つの条件の下で、ハッシュ関数を作成する必要があります。

  • メソッドに渡されるものについては何も知りませんObject o-それは文字列、整数、または実際のカスタムオブジェクトです。
  • 通話hashCode()は一切できません。

ハッシュコードを計算するために、私が現在使用しているアプローチ:

  1. オブジェクトをバイト ストリームに書き込みます。
  2. バイト ストリームをバイト配列に変換します。
  3. バイト配列をループし、次のようにしてハッシュを計算します。

    ハッシュ = ハッシュ * PRIME + byteArray[i]

私の質問はまずまずのアプローチであり、それを改善する方法はありますか? 個人的には、この関数の範囲が広すぎるように感じます。オブジェクトが何であるかについての情報はありませんが、この状況ではほとんど何も言えません。

4

5 に答える 5

3

独自のソリューションを実装する代わりに、HashCodeBuilder.reflectionHashCodeを使用できます。

于 2011-07-08T13:56:09.620 に答える
1

シリアル化アプローチは、実際にシリアル化可能なオブジェクトに対してのみ機能します。したがって、すべてのタイプのオブジェクトに対して実際に可能というわけではありません。

また、これは have equal object graphsによってオブジェクトを比較しますが、これはare equal by.equals()と必ずしも同じではありません。

たとえば、同じコード (同じデータを持つ) によって作成された StringBuilder オブジェクトは、等しい OOS 出力 (つまり、等しいハッシュ) をもち、 whileはb1.equals(b2)false であり、同じ要素を持つ ArrayList と LinkedList は、異なるものとして登録されます。list1.equals(list2)true


後で反復するために配列として保存するのではなく、単純にバイト データを取得してハッシュするカスタム を作成することで、バイト ストリームを配列に変換するステップを回避できます。HashOutputStream

class HashOutputStream extends OutputStream {

    private static final int PRIME = 13;
    private int hash;

    // all the other write methods delegate to this one
    public void write(int b) {
        this.hash = this.hash * PRIME + b;
    }

    public int getHash() {
        return hash;
    }
}

次に、このクラスのオブジェクトを ObjectOutputStream でラップします。

あなたの方法の代わりに、y = y*13 + x他のチェックサムアルゴリズムを見るかもしれません。たとえば、java.util.zip にはAdler32(形式で使用zlib) とCRC32(形式で使用) が含まれgzipます。

于 2011-07-08T14:03:41.873 に答える
0

hash =(hash * PRIME + byteArray [i])%MODULO?

于 2011-07-08T13:45:25.040 に答える
0

また、衝突をできるだけ避けたい場合は、手順 3 で標準化された (意図的な衝突が問題になる場合は暗号化された) ハッシュ関数 (SHA-2 など) を使用できますか?

を見てくださいDigestInputStream。これにより、ステップ 2 も省略できます。

于 2011-07-08T13:45:59.203 に答える
0

非暗号化ハッシュに関するBob Jenkin の記事をご覧ください。彼は多くのアプローチについて説明し、それらの長所、短所、および速度と衝突の可能性との間のトレードオフについて説明します。

他に何もないとしても、アルゴリズムの決定を正当化することができます。正確さよりもスピードを選んだ理由、またはその逆を選んだ理由をインストラクターに説明してください。

出発点として、彼のOne-at-a-time hash を試してください:

ub4 one_at_a_time(char *key, ub4 len)
{
  ub4   hash, i;
  for (hash=0, i=0; i<len; ++i)
  {
    hash += key[i];
    hash += (hash << 10);
    hash ^= (hash >> 6);
  }
  hash += (hash << 3);
  hash ^= (hash >> 11);
  hash += (hash << 15);
  return (hash & mask);
} 

シンプルですが、より複雑なアルゴリズムに対して驚くほどうまく機能します。

于 2011-07-08T14:55:05.823 に答える