2017-04-25 95 views
0

爲什麼hashmap查找失敗? 我克隆鍵入此代碼來模擬從第二個來源接收副本的密鑰。 key和key2都是相同的字節數組。HashMap查找返回null

從註釋掉部分,可以確認的是,哈希表確實包含值。那麼爲什麼查找失敗?

public class NewClass { 
    public static void main(String[] args) { 
     HashMap<byte [], String> lookupTable = new HashMap<>(); 

     byte[] key = new byte[32], key2; 
     SecureRandom sr = new SecureRandom(); 
     sr.nextBytes(key); 


     String value = Arrays.toString(key);   
     lookupTable.put(key, value); 


     key2 = key.clone(); 

     //System.out.println(Arrays.toString(key)); 
     //System.out.println(Arrays.toString(key2)); 

     System.out.println("Keys equal: "+ Arrays.equals(key2, key)); 

     String retrivedValue; 
     /* 
     Set<byte[]> keySet = lookupTable.keySet(); 
     for(byte[] k :keySet){ 
     System.out.println("key in map : "+ Arrays.toString(k)); 
     retrivedValue = keyLookupTable.get(k); 
     System.out.println("Test lookup sucessful:"+retrivedValue.equals(value)); 
     } 
     */ 
     retrivedValue = lookupTable.get(key2); 
     try { 
      System.out.println("Test lookup sucessful:" + retrivedValue.equals(value)); 
     } catch (NullPointerException e) {    
      System.out.println("retrivedValue is "+retrivedValue); 
     } 
    } 
} 

輸出:

Keys equal: true 
retrivedValue is null 
+0

你要比較的hashCode直接equals方法,看看那些比賽。還挖掘到的克隆方法在這裏雜草:https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#clone() – mba12

+0

爲你的程序工件,如當選擇的名字' retrivedValue',爲名稱部分使用傳統拼寫是一個很好的工程。它可以減少下游維護過程中出現錯誤的可能性。 –

回答

2

HashMap查找是不打算使用Arrays.equals,而只是正常.equals,這將爲兩個數組失敗。

這就是爲什麼你基本上不能使用數組作爲映射鍵;你必須用.equals實現將它們包裝在一個類中。

+0

@Soumy,這個答案的要點是數組「equals」實現使用從Object繼承的身份比較,而不是值比較。這意味着即使兩個數組具有相同的內容,但只有它們實際上是相同的數組,它們也是相等的。所以不,你正在搜索的數組不在地圖的關鍵集中。 http://docs.oracle.com/javase/specs/jls/se8/html/jls-10.html#jls-10.7 –

+0

我從OP的職位的猜測是,在他們的例子,因爲他們使用'Arrays.equals'程序,他們明白Object.equals在數組上做了什麼,但不知道地圖如何使用它們。 –

+0

一個解決方法是使用[的ByteBuffers](http://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html#wrap-byte:A-)作爲密鑰,因爲字節緩衝區確實實現一個比較其內容的等價方法。 – VGR