JAva HashMap同じkeyを挿入

2263 ワード

HashMapに重複する値を挿入するには、まずHashMapにどのように要素が格納されているかを明らかにする必要があります.  putメソッド  Mapに格納されている各要素はkey-valueのようなキー値ペアであり、putメソッドで追加されており、同じkeyはMapに関連付けられたvalueが1つしか存在しない.putメソッドのMapでの定義は以下の通りである.
V put(K key, V value); put()メソッド実装:まずhash(key)はkeyのhashcode()を得,hashmapは得られたhashcodeに基づいて挿入する位置のあるチェーンを見つけ,このチェーンの中にはhashcodeと同じEntryキー値ペアが置かれており,このチェーンを見つけた後,equals()メソッドで挿入するキー値ペアが存在するか否かを判断するが,このequalsを比較すると実はkeyである.
key-valueのようなキー値ペアを格納するために使用され、戻り値はkeyがMapに格納した古いvalueであり、以前に存在しなかった場合nullを返します.HashMapのputメソッドはこのように実現される.
public V put(K key, V value) {
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key);
    for (Entry 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;
}

以上から,対応するkey−valueを追加するという組合せの場合,本来対応するkeyが存在していれば,対応するvalueを直接変更し,古いvalueを返し,keyが存在するか否かを判断する際にkeyのhashCodeを比較し,等しいかequalsを比較することが分かる.  直接上のコードから見ると、Map.Entryに対応するhashCodeとkeyのhashCodeを比較しているが、実際にはMap.EntryのhashCodeはkeyを格納するhashCodeである.また、対応するキーが本来存在しない場合は、addEntryを呼び出して対応するキー-valueをMapに追加します.addEntryが伝達するパラメータhashはkeyに対応するhashCodeである.  重複要素の追加  put()法の研究により,keyが存在するか否かを判断する際にkeyのhashCodeを先に比較し,さらに等しいかequalsかを比較するので,hashCode()とequals()法を書き換えることで繰返し要素の添加を実現できることが分かった.
@Override
public int hashCode(){                 
     return this.arga.hashCode() * this.argb.hashCode() ; 
} 

@Override
public boolean equals(Object obj) {   
    if (this == obj) {               
        return true;                  
    }         
    if (!(obj instanceof MyType)) {  
        return false;               
    }    
    MyType p = (MyType) obj;  
    if (this.arga.equals(p.arga) && this.argb.equals(p.argb)) {              
        return true ;                  
    } else {           
        return false ;                
    }       
}

この2つのメソッドを書き換えると重複するキー値ペアを上書きでき、valueを重畳する必要がある場合はput()メソッドを呼び出す前にcontainsKey()メソッドで重複するキー値があるかどうかを判断し、ある場合はget()メソッドで既存のvalueを取得し、新たに追加したvalueを加えるとよい.