ヌルキーのコードが、JDK 1.6以上のバージョンのHashMapで、以前のJDKバージョン(1.5など)と比べて変更されています。JDK 1.6以上のバージョンでHashMapのnullキーのメカニズム変更の利点は何ですか?
JDK1.5では、静的最終オブジェクトNULL_KEYが定義されています。static final Object NULL_KEY = new Object(); maskNull
、unmaskNull
、get
とput
などを含む
メソッドは、このオブジェクトを使用します。
static final Object NULL_KEY = new Object();
static <T> T maskNull(T key) {
return key == null ? (T)NULL_KEY : key;
}
static <T> T unmaskNull(T key) {
return (key == NULL_KEY ? null : key);
}
public V get(Object key) {
Object k = maskNull(key);
int hash = hash(k);
int i = indexFor(hash, table.length);
Entry<K,V> e = table[i];
while (true) {
if (e == null)
return null;
if (e.hash == hash && eq(k, e.key))
return e.value;
e = e.next;
}
}
public V put(K key, V value) {
K k = maskNull(key);
int hash = hash(k);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
if (e.hash == hash && eq(k, e.key)) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, k, value, i);
return null;
}
を見るしかし、このようなオブジェクト(NULL_KEY)がJDK 1.6またはバージョン上で使用されていません。
代わりに、getForNullKey()
とputForNullKey(value)
という2つの新しい方法が同様にget
とput
方法に適用される、添加されます。次のように
public V get(Object key) {
if (key == null)
return getForNullKey();
Entry<K,V> entry = getEntry(key);
return null == entry ? null : entry.getValue();
}
private V getForNullKey() {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null)
return e.value;
}
return null;
}
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
/**
* Offloaded version of put for null keys
*/
private V putForNullKey(V value) {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(0, null, value, 0);
return null;
}
変更は常に変化のためにその理由を持って、次の2質問で私を助けてくださいなどimproving the performance
として、
Q#1 == >なぜこの変更が行われたのですか?JDK 1.5で実装されたHashMapのnullキーに問題が発生するというシナリオがありますか?
Q#2 ==>JDK 1.6またはバージョン以上のHashMapのnullキーメカニズムの変更の利点は何ですか?
この質問は、プログラマーズ・スタック・エクスチェンジ・コムに属しているため、話題にはならないようです –