2012-05-22 90 views
2

對不起......這個愚蠢/愚蠢的問題,夥計們:的HashMap與覆蓋equals和hashCode不工作

爲什麼沒有被應用equals()hashCode()

目前它們只能按照我對HashSet的預期工作。

UPDATE

即使鍵值5重複,但是它不調用equals和hashCode。

我想將其應用於Value。

就像這個例子中HashSet調用equal和hashCode一樣,爲什麼hashMap沒有被調用equals和hashCode,即使是key。

UPDATE2 - ANSWER

HashMap中的鍵(類 - >的hashCode,等於)將被調用。 謝謝大家。 我對此有點困惑。 :)

public class Employee { 

     int id; 
     String name; 
     int phone; 

     public Employee(int id, String name, int phone) { 
      this.id = id; 
      this.name = name; 
      this.phone = phone; 
     }  
    // Getter Setter 

     @Override 
     public boolean equals(Object obj) { 

      if (obj == null) { 
       return false; 
      } 
      if (getClass() != obj.getClass()) { 
       return false; 
      } 
      final Employee other = (Employee) obj; 
      System.out.println("Employee - equals" + other.getPhone()); 
      if (this.id != other.id) { 
       return false; 
      } 
      if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { 
       return false; 
      } 
      if (this.phone != other.phone) { 
       return false; 
      } 
      return true; 
     } 

     @Override 
     public int hashCode() { 
      System.out.println("Employee - hashCode"); 
      int hash = 3; 
      hash = 67 * hash + this.id; 
      hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0); 
      hash = 67 * hash + this.phone; 
      return hash; 
     } 
    } 

____________________________________________________________________________________ 

public class MapClass { 

    public static void main(String[] args) { 
     Map<Integer,Employee> map = new HashMap<Integer,Employee>(); 
     map.put(1, new Employee(1, "emp", 981)); 
     map.put(2, new Employee(2, "emp2", 982)); 
     map.put(3, new Employee(3, "emp3", 983)); 
     map.put(4, new Employee(4, "emp4", 984)); 
     map.put(5, new Employee(4, "emp4", 984)); 
     **//UPDATE** 
     map.put(5, new Employee(4, "emp4", 984));    

     System.out.println("Finish Map" + map.size()); 
     Set<Employee> set = new HashSet<Employee>(); 

     set.add(new Employee(1, "emp", 981)); 
     set.add(new Employee(2, "emp2", 982)); 
     set.add(new Employee(2, "emp2", 982)); 
     set.add(new Employee(3, "emp3", 983)); 
     set.add(new Employee(4, "emp4", 984)); 
     set.add(new Employee(4, "emp4", 984)); 

     System.out.println(set.size()); 
    } 
} 

輸出爲

Finish Map5 
Employee - hashCode 
Employee - hashCode 
Employee - hashCode 
Employee - equals982 
Employee - equals982 
Employee - hashCode 
Employee - hashCode 
Employee - hashCode 
Employee - equals984 
Employee - equals984 
4 
+1

究竟是什麼問題?請記住,在HashMap中,密鑰被哈希,而不是值 –

+0

我將如何調用哈希映射的hascode&equals –

+0

Map調用equals和hashCode方法,並且這樣做 - 對於整數鍵!如果您希望Map檢查Employee hashCode和/或equals,那麼Employee必須是Key而不是Value。 –

回答

6

即使鍵值5重複,但是它不調用equals和hashCode

是它調用的hashCode,對鍵,整數。

我也想它適用於價值

現實的劑量:Java的包含HashMap不工作的方式。他們僅檢查重複項的關鍵字,而不檢查重複項的值,這是應該的。

如果你想要在Map中檢查員工的哈希值,那麼它必須必須是是關鍵。期。

另一種可能的解決方案是下載其中一個可用的多圖。

編輯地看到,它調用的hashCode和equals一樣,所以你的地圖的主要類型更改爲:

class MyInt { 
    private Integer i; 

    public MyInt(Integer i) { 
     this.i = i; 
    } 

    public Integer getI() { 
     return i; 
    } 

    @Override 
    public int hashCode() { 
     System.out.println("MyInt HashCode: " + i.hashCode()); 
    return i.hashCode(); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     System.out.printf("MyInt equals: [%s, %s]%n", i, obj); 
     if (this == obj) 
     return true; 
     if (obj == null) 
     return false; 
     if (getClass() != obj.getClass()) 
     return false; 
     MyInt other = (MyInt) obj; 
     if (i == null) { 
     if (other.i != null) 
      return false; 
     } else if (!i.equals(other.i)) 
     return false; 
     return true; 
    } 

    @Override 
    public String toString() { 
     return i.toString(); 
    } 

} 

然後填寫你的地圖,像這樣:

Map<MyInt,Employee> map = new HashMap<MyInt,Employee>(); 
    map.put(new MyInt(1), new Employee(1, "emp", 981)); 
    map.put(new MyInt(2), new Employee(2, "emp2", 982)); 
    map.put(new MyInt(3), new Employee(3, "emp3", 983)); 
    map.put(new MyInt(4), new Employee(4, "emp4", 984)); 
    map.put(new MyInt(5), new Employee(4, "emp4", 984)); 
    map.put(new MyInt(5), new Employee(4, "emp4", 984)); 

和你」請參閱:

MyInt HashCode: 1 
MyInt HashCode: 2 
MyInt HashCode: 3 
MyInt HashCode: 4 
MyInt HashCode: 5 
MyInt HashCode: 5 
MyInt equals: [5, 5] 
+0

@Ravi:如果Employee是HashMap的*鍵*,你會看到被調用的hashCode方法。看看我上面的編輯,看看HashMap如何調用hashCode和equals。 –

+1

謝謝,我明白了,HashMap的關鍵(class-> hashCode)會被調用。 –

+0

@Ravi:*確切*正確 –

3

HashMap中使用密鑰值的等號/的hashCode(你的情況整數)。我想這就是你要問的,對吧?

您在地圖中重複的原因是您對同一個員工使用了新密鑰。

map.put(4, new Employee(4, "emp4", 345)); 
    map.put(5, new Employee(4, "emp4", 345)); // You are using 5 as the key 
              // for the "same" object you did 
              // in the previous line 

如果你不喜歡的東西

// in main 
    addEmployee(new Employee(4, "emp4", 345)); 
    addEmployee(new Employee(4, "emp4", 345)); 

    private void addEmployee(Employee e) 
    { 
    map.put(e.getId(), e); 
    } 

然後,你不會看到你的集合中的任何重複。

+0

我想重寫hashCode和Equals,但在HashMap'Equals&hashCode'中不會覆蓋。 我想將它應用於價值 –

+0

@Ravi:這沒有意義。 HashMap工作正常。你只是不瞭解密鑰正在被檢查。 –

+0

只需要確認就像本示例中的HashSet調用equal和hashCode一樣,即使爲key也不會調用hashMap。 –

3

HashMap使用鍵作爲索引,而不是值。 (即hashCode()方法,也許等於()被調用的Integer類在上面的代碼中)

0

您使用的是HashMap<Integer, Employee>,它看起來像,所以Integer旨意被散列。由於鍵1,2,3,4,5,你HashMap的大小應該是5

+0

但是當你運行它顯示大小是5 –

+0

對不起,這是一個錯字。 –

相關問題