6

hashCode()はどのように実装されますか?

私の仮定では、ハッシュ関数を実行する初期番号(シード)としてオブジェクトのメモリ位置を使用します。ただし、そうではありません。

私はハッシュも見てきました:それは内部でどのように機能しますか?しかし、それは私の質問に答えません。

はい、SDKをダウンロードすることはできましたが、それを実行してコードを確認する前に、おそらく他の誰かがすでにSDKについて知っています。

ありがとう :)

編集: 私はそれがオーバーライドされるべきであることなどを知っているので、トピックにとどまるようにしてください:)

4

5 に答える 5

23

ダメダメダメ。このスレッドのすべての答えは間違っているか、少なくとも部分的にしか正しくありません。

まず Object.hashCode()、はネイティブメソッドであるため、その実装はJVMのみに依存します。HotSpotと、 JRockitIBMJ9などの他のVM実装との間で異なる場合があります。

あなたが尋ねている場合:

JavaでどのようにhashCode()実装されていますか?

答えは次のとおりです。使用しているVMによって異なります。

OracleのデフォルトのJVM(HotSpot)を使用していると仮定すると、HotSpotには6つのhashCode()実装があることがわかります。-XX:hashCode=nコマンドラインからJVMを実行しているフラグを使用して選択できます。ここで、次のnようになります。

0 – Park-Miller RNG (default)
1 – f(address, global_statement)
2 – constant 1
3 – Serial counter
4 – Object address
5 – Thread-local Xorshift

上記はこの投稿からコピーされています。

また、HotSpotのソースコードを少し掘り下げると、以下のスニペットが見つかります。

if (hashCode == 0) {
  value = os::random();
} else {
  ...

os::random()Park-Miller疑似ランダムジェネレータアルゴリズムの実装にすぎません。

それで全部です。メモリアドレスの概念はありません。他の2つの実装、 1および 4はオブジェクトのメモリアドレスを使用しますが、デフォルトの実装では使用されません。オブジェクトのアドレスに基づく
概念は、主に歴史的なアーティファクトであり、もはや真実ではありません。Object.hashCode()


Object#hashCode()JavaDoc内で次のように読むことができることを私は知っています:

(...)これは通常、オブジェクトの内部アドレスを整数に変換することによって実装されますが、この実装手法はJava™プログラミング言語では必要ありません。

しかし、それは時代遅れで誤解を招くものです。

于 2014-11-17T15:21:26.673 に答える
5

もちろん、これは実装固有ですが、通常、オブジェクトのハッシュコードは遅延計算され、オブジェクトヘッダーに格納されます。奇妙なことは、複雑なロックアルゴリズムを可能にしながら、ヘッダーを小さく保つためにヘッダーを使用して行われます。

OpenJDK / Oracle JVMでは、初期ハッシュコードを計算する通常の方法は、最初の要求時のメモリアドレスに基づいています。オブジェクトはメモリ内を移動するため、毎回アドレスを使用することは適切ではありません。ハッシュコードは実際のアドレスではありません。通常は8の倍数であり、特に2の累乗のハッシュテーブルで直接使用するのには適していません。IDハッシュコードは一意ではないことに注意してください。

HotSpotには、テスト目的で常にゼロを使用するか、安全な乱数ジェネレーター(SRNG)を使用するビルド時間オプションがあります。

于 2012-04-11T13:38:55.497 に答える
0

hashcode()関数の実装は、オブジェクトごとに異なります。特定のクラスがhashcode()をどのように実装するかを知りたい場合は、そのクラスを検索する必要があります。

于 2012-04-11T13:39:57.657 に答える
0

クラスObjectによって定義されたhashCodeメソッドは、個別のオブジェクトに対して個別の整数を返します。これは、オブジェクトの内部アドレスを整数に変換することで実装できます(ただし、この実装スタイルは標準では必要ありません)。ハッシュテーブル(equalおよびhashCode)をサポートするためにhashCodeをオーバーライドする新しいクラスで興味深いものになります: http ://www.javapractices.com/topic/TopicAction.do?Id = 28

于 2012-04-11T13:43:13.090 に答える
-1

メソッドはオーバーライドできるし、オーバーライドする必要があるので、のObject実装について話していると思います。hashCode

実装に依存します。Sun JDKの場合、これはオブジェクトのメモリアドレスに基づいています。

于 2012-04-11T13:26:55.007 に答える