Java 为什么整数键在HashMap中不起作用?

Java 为什么整数键在HashMap中不起作用?,java,hashmap,hashcode,Java,Hashmap,Hashcode,请输入以下代码: public static void main (String[] args) { Map<Number, String> map = new HashMap<Number, String>(); map.put(1L, "test"); System.out.println(map.get(1)); } publicstaticvoidmain(字符串[]args){ Map Map=newhashmap(); 地图放置(1L

请输入以下代码:

public static void main (String[] args) {
    Map<Number, String> map = new HashMap<Number, String>();
    map.put(1L, "test");
    System.out.println(map.get(1));
}
publicstaticvoidmain(字符串[]args){
Map Map=newhashmap();
地图放置(1L,“测试”);
System.out.println(map.get(1));
}
为什么HashMap.get返回null?它必须为hashCode函数返回1的任何对象返回值,不是吗

已更新

问题是映射接口接收对象,而不是参数化类型。所以我期望任何对象都可以是键,但HashMap实现检查类型为equals,这让我感到惊讶


而自动装箱不是问题所在。我知道,1变成了整数,1L变长。但是它们有相同的哈希代码。因此,正如我所想,任何实现映射#get都应该为具有相同哈希代码的任何对象返回值。

put和get之间存在类型不匹配

这里发生的是自动装箱,Java将自动执行原语到它的
对象
等价物之间的转换,反之亦然,而不是通过
new()

尝试以下方法:

public static void main (String[] args) {
        Map<Number, String> map = new HashMap<Number, String>();
        map.put(1L, "test");
        System.out.println(map.get(1L));
    }
这就是这里的问题,这是通过使用自动装箱实现的

一个简单的例子

        Long l = new Long(1);
        Integer i = new Integer(1);
        System.out.println(i.equals(l)); //false -->Hashmap get() failed here
        System.out.println(i.intValue() ==l.intValue());//true

您输入的键为1L(
Long
),得到的键为1(
Integer

它们不是一回事,所以要小心


从put中删除L,或将L添加到get。或者更好的方法是,不要将它们写为原语并依赖于自动装箱。

这是因为在检索值时传递的不是长类型的键,而是一个整数。它们作为不同的对象自动装箱,因此不代表同一个键。

我发现了问题,请参阅java.util.HashMap#获取源代码,它包含:

public V get(Object key) {
        if (key == null)
            return getForNullKey();
        int hash = hash(key.hashCode());
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                return e.value;
        }
        return null;
    }
public V get(对象键){
if(key==null)
返回getForNullKey();
int hash=hash(key.hashCode());
for(条目e=表[indexFor(hash,table.length)];
e!=null;
e=e.next){
对象k;
如果(e.hash==hash&((k=e.key)==key | | key.equals(k)))
返回e.value;
}
返回null;
}

因此,在返回值之前,它会使用equals检查key。

整数和long不相同

Integer#等于

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}
public boolean equals(Object obj) {
    if (obj instanceof Long) {
        return value == ((Long)obj).longValue();
    }
    return false;
}
Long#等于

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}
public boolean equals(Object obj) {
    if (obj instanceof Long) {
        return value == ((Long)obj).longValue();
    }
    return false;
}

尝试
System.out.println(map.get(1L))整数1和长1L具有相同的哈希代码,并且将存储在映射内的同一个bucket中,这是正确的。但是
.equals
完成并返回false。java.util.HashMap#get有什么问题?实际上,您的问题不在于
get
它的意思是为什么equals失败?这是因为
自动装箱
:)或不使用HashMap而使用HashMapinstead@TwoThe事实上,我甚至没有注意到这一点。