2015-12-15 32 views
2

我写了下面的代码,并输出I想到的是“你好世界”自动装箱在哈希表返回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); 
    } 
} 

回答

6

您无法将字节自动装箱到整数。

这个混淆来自事实,即Map的get方法把key当作Object,而不是像你的map的key类型中指定的Integer。所以你可以做这样的事情:

String s = hm.get("hello"); 

它没有sence,当然,但不会有编译错误。

要解决,你应该手动字节转换为整数(或INT):

String s = hm.get((int)b); 
1

Java正在自动装箱bByte,这是不是一个Integer

即使它可以推断Integer类型,Java也不会自动执行自动扩展转换自动转换转换(以前)。

1

这与自动装箱无关。 HashMap在内部与对象类一起工作。考虑

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()方法存储在表HashMap.java

的源代码。到目前为止,您的 get(b)有一个字节作为重点线会的工作,因为这是真的:

byte b = 1; 
int i = 1; 
((Object)b).hashCode() == ((Object)i).hashCode() //true, both are 1 

所以在HashMap.get方法循环查找表中的相应条目。
但后来有这if声明。让我们分解它:

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

  2. (k = e.key) == key这是不正确的。 (Object)b != (Object)i。这必须是完全相同的对象才是真实的。

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

所以你的条目中发现,但字节的密钥失效的futher检查,你会得到空的结果。除非你使用整数。