web-dev-qa-db-ja.com

NullキーとNull値を持つHas​​hMap

次のコードを検討してください。

import Java.util.*;

class Employee {

    String name;

    public Employee(String nm) {
        this.name=nm;
    }
}

public class HashMapKeyNullValue {

    Employee e1;

    public void display(){

        Employee e2=null;
        Map map=new HashMap();

        map.put(e2, "25");
        System.out.println("Getting the Value When e2 is set as KEY");
        System.out.println("e2 : "+map.get(e2));
        System.out.println("e1 : "+map.get(e1));
        System.out.println("null : "+map.get(null));

        map.put(e1, "");
        System.out.println("Getting the Value when e1 is set as KEY");
        System.out.println("e2 : "+map.get(e2));
        System.out.println("e1 : "+map.get(e1));
        System.out.println("null : "+map.get(null));

        map.put(null, null);   // null as key and null as value
        System.out.println("Getting the Value when setting null as KEY and null as value");
        System.out.println("e2 : "+map.get(e2));
        System.out.println("e1 : "+map.get(e1));
        System.out.println("null : "+map.get(null));

        map.put(null, "30");
        System.out.println("Getting the Value when setting only null as KEY");
        System.out.println("e2 : "+map.get(e2));
        System.out.println("e1 : "+map.get(e1));
        System.out.println("null : "+map.get(null));
    }

    public static void main(String[] args) {

        new HashMapKeyNullValue().display();

    }
}

プログラムの出力は次のとおりです。

Getting the Value When e2 is set as KEY
e2 : 25
e1 : 25
null : 25
Getting the Value when e1 is set as KEY
e2 : 
e1 : 
null : 
Getting the Value when setting null as KEY and null as value
e2 : null
e1 : null
null : null
Getting the Value when setting only null as KEY
e2 : 30
e1 : 30
null : 30

ここで、キーとしてe1, e2, and nullがどのように相互に関連しているか。 3つすべてが同じハッシュコードに割り当てられていますか?はいの場合、なぜですか?

3つすべてが異なって見えるため、1つの値の変更が他の値を変更します。キーのエントリが1つだけHashMapまたはe1, e2, or nullに作成されるということは、すべて同じキーのように扱われるためです。

14
Nizam

HashMapは、nullがキーおよびnullキーとして渡されたときにハッシュコードを呼び出さない特別なケースとして扱われます。

Putメソッド

HashMap putsnullキーをバケットに0 およびnullを渡された値のキーとしてマップします。 HashMapは、リンクリストデータ構造によってそれを行います。 HashMapは内部でリンクリストデータ構造を使用します。

HashMapHashMap.Javaの静的クラス)が使用するリンクリストデータ構造

static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        Entry<K,V> next;
        final int hash;
}

Entryクラスでは、[〜#〜] k [〜#〜]nullに設定され、値は渡された値にマップされますputメソッド。

メソッド取得

Hashmap getメソッドでは、キーがnullとして渡されるかどうかをチェックします。バケット内のnullキーの検索値。

そのため、1つにnullキーは1つしか存在できませんhashmapobject。

38
Sandeep Vaid

nullをマップキーとして渡すと、0 bucket。 nullキーのすべての値がそこに行きます。これが同じ値を返す理由です。提供するすべてのキーはnullであり、HashMapの同じバケットにあります。

6
Kamil Kłys

null keyの場合、Hashmap実装はそれを特別なケースと見なし、代わりにEntryオブジェクトを0バケットの場所に格納するhashCodeメソッドを呼び出しません。

2
Ravi Soni

HashMapにNULLを入力すると、キーとしてNULLを入力しようとしているかどうか(putForNullKey()と呼ばれる)特別なチェックが行われます。これは特殊なケースであり、null以外のオブジェクトを配置しようとするのとは異なり、ハッシュ計算を行わないこともあります。

public V put(K key, V value) {
    if (table == EMPTY_TABLE) {
        inflateTable(threshold);
    }
    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;
}

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;
}
1
Mykola Evpak

HashMapは、キーごとに1つの値のみを保存できます。より多くの値を保存する場合は、MultivalueHashMapを使用する必要があります(Google GuavaおよびApache Commons Collectionsには、そのようなマップの実装が含まれています)。

e1とe2の値はnullです。オブジェクトを割り当てないためです。したがって、これらの変数を使用すると、そのマップエントリのキーもnullになり、結果が得られます。 Nullにはハッシュコードはありませんが、HashMapのキーとして許容されます(Nullをキーとして許可しない他のMap実装があります)。

1
dunni