2015-12-15 28 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檢查,你會得到空的結果。除非你使用整數。