哈希映射中的自动装箱返回NULL

时间:2015-12-15 07:11:22

标签: java hashmap

我写了下面的代码,输出我希望是'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);
   }
 }

3 个答案:

答案 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声明。让我们分解一下:

  1. (e.hash == hash)这仍然是真的。 put方法在创建新条目时也使用默认的hashCode()方法并存储此值。

  2. (k = e.key) == key事实并非如此。 (Object)b != (Object)i。这必须是完全相同的对象。

  3. key.equals(k)这也不是真的:

  4. 因此找到了您的条目,但字节键未通过进一步检查,结果为null。除非你使用整数。