我写了下面的代码,输出我希望是'Hello World'
我得到了null,有人可以解释这种行为。
import java.util.*;
public class Test {
static HashMap<Integer,String> hm = new HashMap<Integer, String>();
public static void main(String args[]) {
byte b = 1;
hm.put(1, "Hello World");
String s = hm.get(b);
System.out.println("The result is: " + s);
}
}
答案 0 :(得分:6)
您不能对整数字节执行自动装箱。
这种混淆来自Map&#39的get方法将key作为Object,而不是地图键类型中指定的Integer。所以你可以这样做:
String s = hm.get("hello");
当然没有任何意义,但是没有编译错误。
要修复你应该手动将字节转换为整数(或int):
String s = hm.get((int)b);
答案 1 :(得分:1)
Java将b
自动装箱到Byte
,而Integer
不是sudo sync
sudo sysctl -w vm.drop_caches=3
。
即使它可以推断整数类型,Java也不会执行自动扩展转换和自动转换(永远)。
答案 2 :(得分:1)
这与自动装箱无关。 HashMap在内部使用Object Classes。查看HashMap.java的源代码
public V get(Object key) {
[...]
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;
}
条目按hashCode()
方法存储在表格中。到目前为止,你的get(b)
行有一个字节作为键可以工作,因为这是真的:
byte b = 1;
int i = 1;
((Object)b).hashCode() == ((Object)i).hashCode() //true, both are 1
因此HashMap.get
方法中的for循环在表中找到相应的条目
但是有这个if
声明。让我们分解一下:
(e.hash == hash)
这仍然是真的。 put
方法在创建新条目时也使用默认的hashCode()
方法并存储此值。
(k = e.key) == key
事实并非如此。 (Object)b != (Object)i
。这必须是完全相同的对象。
key.equals(k)
这也不是真的:
因此找到了您的条目,但字节键未通过进一步检查,结果为null。除非你使用整数。