142

Java String の hashCode 値は ( String.hashCode() ) として計算されます。

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

次の式が false と評価される状況 (JVM のバージョン、ベンダーなど) はありますか?

boolean expression = "This is a Java string".hashCode() == 586653468

更新 #1:答えが「はい、そのような状況がある」と主張する場合は、「これは Java 文字列です」.hashCode() != 586653468 の具体例を挙げてください。具体的/具体的になるようにしてください。できるだけ。

更新 #2: hashCode() の実装の詳細に依存することは一般的に悪いことです。ただし、私は特に String.hashCode() について話しているので、答えは String.hashCode() に集中してください。Object.hashCode() は、この質問のコンテキストではまったく関係ありません。

4

8 に答える 8

18

JDK 1.0 と 1.1 および >= 1.2 について何かを見つけました:

JDK 1.0.x および 1.1.x では、長い文字列の hashCode 関数は、n 番目の文字ごとにサンプリングすることによって機能していました。これにより、多くの文字列が同じ値にハッシュされることが十分に保証され、ハッシュテーブルの検索が遅くなります。JDK 1.2 では、関数が改善され、これまでの結果に 31 を掛けてから、次の文字を順番に追加するようになりました。これは少し遅くなりますが、衝突を回避するのにははるかに優れています。ソース: http://mindprod.com/jgloss/hashcode.html

数字が必要なように見えるので、何か違う: ハッシュコードの代わりに CRC32 または MD5 を使用するのはどうですか? 議論も心配もありません...

于 2009-04-24T12:17:35.907 に答える
8

ハッシュ コードが特定の値と等しいことに依存しないでください。同じ実行内で一貫した結果が返されるというだけです。APIドキュメントには次のように書かれています:

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

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

EDIT String.hashCode() の javadoc は String のハッシュ コードの計算方法を指定しているため、これに違反すると公開 API 仕様に違反します。

于 2009-04-24T09:16:12.207 に答える
5

上で述べたように、一般に、クラスのハッシュ コードが同じままであることに依存するべきではありません。同じ VMで同じアプリケーションを後で実行しても、異なるハッシュ値が生成される可能性があることに注意してください。私の知る限り、Sun JVMのハッシュ関数は実行ごとに同じハッシュを計算しますが、それは保証されていません。

これは理論的なものではないことに注意してください。java.lang.String のハッシュ関数は JDK1.2で変更されました (古いハッシュは、URL やファイル名などの階層的な文字列に問題がありました。これは、文字列に対して同じハッシュを生成する傾向があり、最後だけが異なるためです)。

java.lang.String は特別なケースです。その hashCode() のアルゴリズムは (現在) 文書化されているため、おそらくそれに頼ることができます。私はまだそれを悪い習慣だと考えています。文書化された特別なプロパティを持つハッシュ アルゴリズムが必要な場合は、それを記述してください :-)。

于 2009-04-24T09:23:31.423 に答える
3

心配すべきもう 1 つの (!) 問題は、Java の初期バージョンと後期バージョンの間で実装が変更される可能性があることです。実装の詳細が確定しているとは思えないため、将来のJava バージョンへのアップグレードで問題が発生する可能性があります。

結論として、私は の実装には依存しませんhashCode()

おそらく、このメカニズムを使用して実際に解決しようとしている問題を強調すると、より適切なアプローチが強調されます。

于 2009-04-24T09:16:18.697 に答える
2

変更や互換性のない VM が心配な場合は、既存の hashcode 実装を独自のユーティリティ クラスにコピーし、それを使用して hashcodes を生成してください。

于 2009-04-24T15:27:36.307 に答える