有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

具有空键和空值的java HashMap

考虑下面的代码:

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 nullas键是如何相互关联的。是否所有三个都分配给相同的哈希代码?若有,原因为何

因为这三个看起来都不一样,所以一个值的变化会改变另一个值。这是否意味着只有一个密钥条目被放入HashMap或者e1, e2, or null中,因为所有条目都被视为相同的密钥


共 (5) 个答案

  1. # 1 楼答案

    > <强> null <强>键,Hash映射实现将其视为特殊情况,不调用HASCODE方法,而是将条目对象存储到0个桶位置。p>

  2. # 2 楼答案

    HashMap在将null作为键传递时,不调用hashcode,而将null键作为特例处理

    Put方法

    ^{null键放入bucket0并将null映射为传递值的键。HashMap是通过链表数据结构实现的。HashMap在内部使用链表数据结构

    HashMap使用的链表数据结构(在^{中是一个静态类)

    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方法中传递的值

    获取方法

    而在Hashmapget方法中,检查键是否作为null传递。在bucket0中搜索null键的值

    因此在一个hashmap对象中只能有一个空键

  3. # 3 楼答案

    当您将NULL放入HashMap时,会特别检查您是否试图将NULL放入密钥(称为putForNullKey())。这是一种特殊情况,它的工作原理不像你试图放置一个非空的对象,正如你可能看到的,它甚至不去进行散列计算

    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;
    }
    
  4. # 4 楼答案

    如果将null作为映射键传递,它将转到0 bucket。null key的所有值都将转到那里。这就是为什么它返回相同的值,因为您提供的所有键都是null,并且在HashMap的同一个bucket中

  5. # 5 楼答案

    HashMap每个键只能存储一个值。如果想要存储更多的值,就必须使用多值hashmap(Google Guava和Apache Commons集合包含这种映射的实现)

    e1和e2的值为null,因为您没有为它们分配任何对象。因此,如果使用这些变量,映射项的键也为null,这将导致结果。Null没有任何哈希代码,但允许在HashMap中作为键(还有其他Map实现不允许Null作为键)