2009-12-18 108 views
2

一位同事遇到了一個錯誤,其中使用HashMap#containsKey來驗證鍵值對是否存在。指定的鍵是不同的類型,所以該方法總是返回false。例如(假設在地圖中填充了他想要檢索對象):爲什麼HashMap#containsKey需要一個Object類型的參數?

Map<String, String> map = new HashMap<String, String>();
Long value = new Long(12);
boolean hasString = map.containsKey(value);

我的問題是:

爲什麼會出現Map實現力你把K型的按鍵和V類型的值,但containsKey()方法允許指定任何對象?

Map接口中還有其他一些方法,如get()也接受Object類型的參數。

+1

另見http://smallwig.blogspot.com/2007/12/why-does-setcontains-take-object-not -e.html –

+0

不好意思詢問重複的問題,我試着搜索它,但我必須使用錯誤的關鍵字。 – austen

回答

2

我想這是因爲Java的Map實現使用.equals()命令來決定兩個對象是否相等的像.containsKey().remove()方法的目的。由於.equals()與一般對象相比較(如果你重寫它,你通常需要在頂部檢查,如if (!(t instanceof T)) { return false; },但是沒有實際的規定A和B必須是A.equals(B)的同一類型。

下面是一些代碼,突出的差異。也許不是你所期望的。

import java.util.*; 

public class Test { 

    static class Foo implements Comparable { 
     public String a; 

     public boolean equals(Object obj) { 
      if (obj instanceof Bar) { return a.equals((((Bar) obj).b)); } 
      return false; 
     } 

     public int compareTo(Object o) { 
      return this.equals(o) ? 0 : -1; 
     } 
    } 

    static class Bar implements Comparable { 
     public String b; 

     public boolean equals(Object obj) { 
      if (obj instanceof Foo) { return b.equals((((Foo) obj).a)); } 
      return false; 
     } 

     public int compareTo(Object o) { 
      return this.equals(o) ? 0 : -1; 
     } 
    } 

    public static void main(String [] args) { 
     Map<Foo, Bar> test = new TreeMap<Foo, Bar>(); 
     Foo foo = new Foo(); 
     Bar bar = new Bar(); 

     foo.a = "Hello"; 
     bar.b = "Hello"; 

     System.out.println(foo.equals(bar)); 
     System.out.println(bar.equals(foo)); 

     test.put(foo, bar); 

     System.out.println(test.containsKey(bar)); 
     System.out.println(test.containsValue(foo)); 
    } 

} 
相關問題