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事实上,我甚至没有注意到这一点。