7

メモリ内の適切なオブジェクトを見つけるhashCode()のに役立つ (たとえば) メモリ領域を示す本を読みました。HashSetsしかし、Java でメモリを直接操作できない場合、どうしてそれが成り立つのでしょうか? オブジェクトが作成され、ある場所から別の場所に移動されることに加えて、ポインターはありません。開発者はそれについて知りません。

のような認識hashCode() {return 42;}はひどくひどいものだと読みましたが、VM にオブジェクトをどこに置くかを指示できない場合、違いは何ですか?

hashCode()問題は、メモリを操作できない場合、深いレベルでの目的は何ですか?

4

7 に答える 7

9

私は本を​​読んで、hashCode()がメモリ内の適切なオブジェクトを見つけるのに役立つメモリ領域(HashSetなど)を示していることを読みました。

いいえ、それはの目的の完全に偽の説明ですhashCode。これは、潜在的に等しいオブジェクトを効率的に見つけるために使用されます。メモリ内のオブジェクトの場所とは何の関係もありません。

HashMapのようなものがある場合、ルックアップを実行するときに一致するキーをすばやく見つけたいという考え方です。したがって、最初に要求されたキーのハッシュコードを確認してから、そのハッシュコードを使用してマップ内のすべてのキーを非常に効率的に見つけることができます。次に、それらの(そしてそれらだけの)候補キーのそれぞれが、要求されたキーと等しいかどうかをチェックできます。

詳細については、ハッシュテーブルに関するウィキペディアの記事を参照してください。

于 2013-02-06T17:34:50.163 に答える
6

Jon Skeetの答え(+1)が好きですが、ハッシュテーブルがどのように機能するかを知る必要があります。ハッシュテーブルはデータ構造であり、基本的にはバケットの配列であり、キーのハッシュコードを使用して、そのエントリを貼り付けるバケットを決定します。これにより、そのキーにあるものを取得するための将来の呼び出しで、全体をふるいにかける必要がなくなります。ハッシュテーブルに格納されているもののリスト。ハッシュテーブルはキーのハッシュコードを計算し、一致するバケットに直接移動してそこを確認できます。ハッシュコードはすばやく計算できるものである必要があり、一意であることが望ましいですが、そうでない場合は、最悪の場合(your return 42;)を除いて、災害ではありません。これは、すべてが同じになるため、悪いことです。バケツとあなたはすべてをふるいにかけることに戻っています。

Object#hashCodeのデフォルト値は、便利な種類の乱数であるという理由だけでメモリ位置のようなものに基づいている場合がありますが、メモリ管理中にオブジェクトが回避されるため、その値はキャッシュされ、誰も気にしません。StringやBigDecimalなどのさまざまなオブジェクトによって作成されたハッシュコードは、確かにメモリとは関係ありません。これは、すぐに生成される数値であり、多くの場合、一意であることを望んでいます。

于 2013-02-06T17:51:41.063 に答える
1

ハッシュコードは単なる「値」です。「MyClassobj=new MyClass()」が「obj」がメモリ内に配置される場所と関係があるのと同じように、「メモリ内のどこに配置するか」とは何の関係もありません。

では、Java hashCode()とは何ですか?

これは主題に関する良い議論です:

K&Bによると、hashcode()コントラクトは次のとおりです。

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

  2. equals(Object)メソッドに従って2つのオブジェクトが等しくない場合、hashcode()に関する要件はありません。

  3. 2つのオブジェクトでhashcode()を呼び出すと異なる整数の結果が生成される場合、equals(Object)に従って両方が等しくない必要があります。

于 2013-02-06T17:35:05.233 に答える
1

ハッシュコードは、オブジェクトを受け取って数値を出力する関数です。オブジェクトが変更されない場合、オブジェクトのハッシュコードは常に同じです。

オブジェクトを格納する必要があるハッシュマップのような関数は、内部配列のサイズを法とするハッシュコードを使用して、オブジェクトを格納する「メモリ位置」(つまり配列位置) を選択します。

衝突が発生する場合があります (2 つのオブジェクトが同じハッシュコードになってしまうため、もちろん慎重に解決する必要があります)。詳細については、ウィキペディアのハッシュマップエントリを読むことをお勧めします。

于 2013-02-06T17:35:28.910 に答える
0

HashCode はオブジェクトの暗号化であり、その暗号化により、Java は、たとえばコレクション内の 2 つのオブジェクトが同じか異なるかを認識します。(例としてSortedSet)

この記事を読むことをお勧めします。

于 2013-02-06T17:35:06.483 に答える
0

はい、通常はオブジェクトの内部アドレスを変換することで実装されますが、メモリアドレスとは関係ありません。オブジェクトの hashCode()メソッドにある次のステートメントは、実装が強制されていないことを明確に示しています。

合理的に実用的である限り、クラス Object によって定義された hashCode メソッドは、個別のオブジェクトに対して個別の整数を返します。(これは通常、オブジェクトの内部アドレスを整数に変換することによって実装されますが、この実装手法は JavaTM プログラミング言語では必要ありません。

于 2013-02-06T17:40:28.387 に答える
0

このhashCode()関数はオブジェクトを受け取り、数値を出力しますが、これは一意である必要はありません。オブジェクトが変更されない場合、オブジェクトのハッシュコードは常に同じです。

hashCode() によって返される値は、オブジェクトのハッシュ コードであり、オブジェクトのメモリ アドレスを 16 進数で表したものです。

定義により、2 つのオブジェクトが等しい場合、それらのハッシュ コードも等しくなければなりません。equals() メソッドをオーバーライドすると、2 つのオブジェクトを同一視する方法が変更され、Object の hashCode() の実装は無効になります。したがって、equals() メソッドをオーバーライドする場合は、hashCode() メソッドもオーバーライドする必要があります。

詳細については、このJava ハッシュコードの記事 を参照してください。

ここに画像の説明を入力

于 2019-08-03T10:38:02.790 に答える