2012-05-22 55 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

对不起,这是一个错字。 –

相关问题