オブジェクトAPIの hashCode() メソッドを使用してJavaがハッシュ値を生成する方法に興味がありますか?
JavaはhashCode()を生成しません。つまり、ここでは自動化は行われません。ただし、Object
は、オブジェクトのインスタンスのメモリアドレスに基づいてHashCodeを生成します。ほとんどのクラス(特にCollection
APIのいずれかで使用する場合)は、独自のHashCodeを実装する必要があります(契約により、独自のequalsメソッドを実装する必要があります)。
Object
のhashCode()
は実際にはネイティブメソッドであり、実装は実際には純粋なJavaではありません。さて、それがどのように機能するかに関して、 トムホーティンからのこの答え はそれを説明するのに素晴らしい仕事をします:
多くの人が
Object.hashCode
は、メモリ内のオブジェクト表現のアドレスを返します。最新の実装では、オブジェクトは実際にはメモリ内を移動します。代わりに、オブジェクトヘッダーの領域を使用して値を格納します。値は、値が最初に要求されたときのメモリアドレスから遅延して導出される場合があります。
答え全体は実際に読む価値があります。
Java Platform APIのドキュメントによると、ハッシュコードの計算はオブジェクトの32ビット内部JVMアドレスに基づいています。
実行中にオブジェクトが移動するのは事実です(唯一の理由はガベージコレクターです)。ただし、ハッシュコードは変更されません。
だからあなたがこのようなオブジェクトを持っているとき
Person person1 = new Person();
person1.setName("Alex");
Person person2 = new Person();
person2.setName("Alex");
Person person3 = person2;
この場合、これら2つのオブジェクトのメモリアドレスが同じではないため、person1.hashCodeはperson2.hashCodeと等しくなりません。
ただし、person2.hashCodeは同じオブジェクトを指しているため、person3と同じになります。
したがって、オブジェクトにhashCodeメソッドを使用する必要がある場合は、自分で実装する必要があります。
ちなみにString.hashCodeの実装は異なります。これは次のようなものです:(C#構文)
public int hashCode(String str)
{
int h = 0;
for (int i = 0; i < str.Length; i++)
h = (h * 31) + str[i];
return h;
}
edit:ここではオーバーフローチェックが行われないため、hashCodeは正または負の場合があります。
Object.hashCode()は、特定のオブジェクトのID番号に基づくSystem.identityHashCode()を使用します。
HashCode()関数には、ハッシュコードを作成するためのいくつかのオプションがあります。 JVM起動パラメータを設定します。 C++で記述されたhashCode()を作成する関数で、コードを見ることができます ここ
情報は ここ から取得されました
Javaはあなたにとって意味のあるhashCode
を生成しません。有用なhashCode
を生成するのはプログラマーとしてのあなたの仕事です。デフォルトのhashCode
は単なるメモリ位置です。
hashCode
メソッドは数値を出力します。オブジェクトが変更されない場合、オブジェクトのハッシュコードは常に同じです。一意である必要はないことを言及することが重要です。
HashCode()のデフォルトの実装は、オブジェクトのアドレスに基づいてオブジェクトのハッシュコード番号を返すように指定されています。 JVMは、オブジェクトのアドレスに基づいてこの一意の番号を自動的に生成します。
2つのオブジェクトが同じメモリ位置にある場合(2つの参照変数によって参照される同じオブジェクト)、両方のハッシュコード番号は同じになりますが、2つのオブジェクトが異なるメモリ位置にある場合、両方のオブジェクトのハッシュコード番号は異なります。
メソッドをオーバーライドする必要があるため、おそらく質問をしました。しかし、いつそれをオーバーライドするのですか?
HashCode()メソッドのデフォルトの実装は、オブジェクトのアドレスに基づいてハッシュコード番号(オブジェクトの一意のID)を返します。しかし、アプリケーションが(オブジェクトのアドレスではなく)いくつかの異なるパラメーターに基づいてオブジェクトを一意に識別する必要がある場合は、hashCode()メソッドをオーバーライドし、要件に従って実装を行う必要があります。
トピックに関するEffective Java
からの重要なメモ:
詳細については、これをチェックしてください Javaハッシュコードの例 。