2013-11-26 8 views
7

ヌルキーのコードが、JDK 1.6以上のバージョンのHashMapで、以前のJDKバージョン(1.5など)と比べて変更されています。JDK 1.6以上のバージョンでHashMapのnullキーのメカニズム変更の利点は何ですか?

JDK1.5では、静的最終オブジェクトNULL_KEYが定義されています。static final Object NULL_KEY = new Object(); maskNullunmaskNullgetputなどを含む

メソッドは、このオブジェクトを使用します。

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つの新しい方法が同様にgetput方法に適用される、添加されます。次のように

は、ソースコードを参照してください:

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キーメカニズムの変更の利点は何ですか?

+1

この質問は、プログラマーズ・スタック・エクスチェンジ・コムに属しているため、話題にはならないようです –

答えて

2

Documentation for private V getForNullKey()は、getの

オフロードバージョンは()nullキーをルックアップするために言います。ヌルキーは インデックス0にマップされます。このヌルケースは、最も一般的に使用される2つの操作(getと put)ののパフォーマンスの場合はの別個のメソッドに分割されますが、他の場合は条件に組み込まれます。

関連する問題