javaにおけるhashcode()関数の役割


http://www.java3z.com/cwbwebhome/article/article8/83446.html?id=4341
JavaオブジェクトのHashcodeの役割は何ですか?データ構造のハッシュ・テーブル(ハッシュ・リスト)、ハッシュ関数を連想することができる.Object.hashCode()はハッシュ・テーブルというデータ構造を実現するためにハッシュ値を計算するためのハッシュ関数である.
ハッシュテーブルの構造を見てください.
  1つの配列にオブジェクトを格納するとき、hashCodeによって得られたハッシュ値から配列のインデックス位置(通常は剰余演算)を計算し、このインデックス位置に従ってアクセスする.複数のオブジェクトから計算された索引の位置が同じである場合は、チェーンで保存します.衝突はどのように保証しますか?Object.equalsの方法を使います.
hashCodeとequalsは、hashテーブルのようなデータ構造にオブジェクトを格納します.
Java Object.hashCode()
  オブジェクトのハッシュコード値を返します.この方法をサポートすることは、ハッシュ・テーブルのいくつかの利点、例えば、java.util.Hashtableが提供するハッシュ・テーブルを提供することである.
hashCodeの一般協定は、
Javaアプリケーションの実行中に、同じオブジェクト上で何度もhashCodeメソッドを呼び出した場合、同じ整数を返す必要があります.前提はオブジェクト上のequals比較で使用される情報は修正されていません.あるアプリケーションの一回から同じアプリケーションのもう一回まで実行します.この整数は一致を保つ必要がありません.
equals(Object)方法によれば、2つのオブジェクトが等しくなる場合、hashCode方法は、2つのオブジェクトのそれぞれにおいて同じ整数結果を生成しなければならない.
以下の場合は必須ではない:equals方法によれば、2つのオブジェクトが等しくない場合、2つのオブジェクトのいずれかにhashCodeメソッドを呼び出すと、異なる整数結果が生成されるに違いない.しかし、プログラマは、同じではないオブジェクトのために異なる整数結果を生成することは、ハッシュ・テーブルの性能を向上させることができることを知っているはずである.
  上記の協定では、オブジェクトの状態(これらの状態はすべてのフィールドとは限らない.業務によっては)変更されていない場合、何度もhashCodeを呼び出しても同じです.しかし、異なるオブジェクトは同じhashCodeを持つことができるが、できるだけ異なるオブジェクトを同じではないhashCodeにすることで、ハッシュ・テーブルの性能を向上させることができる.
Java Hashtableのgetとputを見て実現します.
public synchronized V get(Object key) {
	Entry tab[] = table;
	int hash = key.hashCode();
	int index = (hash & 0x7FFFFFFF) % tab.length;
	for (Entry< K,V> e = tab[index] ; e != null ; e = e.next) {
	    if ((e.hash == hash) && e.key.equals(key)) {
		return e.value;
	    }
	}
	return null;
}
  まずkey.hashCodeに基づいて配列のインデックス位置indexを探して、hash&0 x 7 FFFFFは正の数であることを保証します.その後、hashとequalsを探します.衝突チェーンが長いほど性能が悪いです.
putを見る方法:
public synchronized V put(K key, V value) {
	// Make sure the value is not null
	if (value == null) {
	    throw new NullPointerException();
	}
	// Makes sure the key is not already in the hashtable.
	Entry tab[] = table;
	int hash = key.hashCode();
	int index = (hash & 0x7FFFFFFF) % tab.length;
	for (Entry< K,V> e = tab[index] ; e != null ; e = e.next) {
	    if ((e.hash == hash) && e.key.equals(key)) {
		V old = e.value;
		e.value = value;
		return old;
	    }
	}
	modCount++;
	if (count >= threshold) {
	    // Rehash the table if the threshold is exceeded
	    rehash();
            tab = table;
            index = (hash & 0x7FFFFFFF) % tab.length;
	}
	// Creates the new entry.
	Entry< K,V> e = tab[index];
	tab[index] = new Entry< K,V>(hash, key, value, e);
	count++;
	return null;
}
はまず同じものがあるかどうかを見てください.その後、配列のスペースが足りなくなり、割り当てられたスペースを再交換し、データをハッシュに保存し直します.最後に衝突チェーンの頭に挿入します.