4

对不起......关于这个愚蠢/愚蠢的问题,伙计们:

为什么不equals()hashCode()应用?

目前他们只按照我的预期工作HashSet

更新

EVEN 键值 5 重复但它不调用 equals 和 hashCode。

我也想把它应用到价值上。

就像在这个例子中 HashSet 调用 equal 和 hashCode 一样,为什么 hashMap 不被称为 equals 和 hashCode 即使是 key。

更新2 - 答案

HashMap 的 key(class->HashCode, equals) 将被调用。谢谢你们。我对此有点困惑。:)

    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
4

4 回答 4

7

EVEN 键值 5 重复但不调用 equals 和 hashCode

是的,它确实在键上调用了 hashCode,即 Integer。

我也想把它应用到价值上

现实的剂量:Java HashMaps 不是那样工作的。他们只检查键的重复项,而不是值,这是应该的。

如果您希望在 Map 中检查 Employee 的哈希,那么它必须是键。时期。

另一种可能的解决方案是下载一个可用的多图。

编辑 以查看它正在调用 hashCode 和 equals,将 Map 的键类型更改为如下所示:

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]
于 2012-05-22T12:59:38.840 回答
3

HashMap 使用键值的equals/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);
  }

那么您将不会在您的收藏中看到任何重复项。

于 2012-05-22T12:48:36.280 回答
3

HashMap 使用键作为索引,而不是值。(那是 hashCode(),也许 equals() 会在上面代码中的 Integer 类上被调用)

于 2012-05-22T12:48:48.940 回答
0

您正在使用 a HashMap<Integer, Employee>,看起来像,所以Integers 将被散列。由于键是1,2,3,4,5,因此您的大小HashMap应该是 5。

于 2012-05-22T12:50:45.110 回答