【问题标题】:HashMap with override equals and hashCode not working具有覆盖等于和 hashCode 的 HashMap 不起作用
【发布时间】:2012-05-22 12:42:36
【问题描述】:

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

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

目前,他们只能按照我对HashSet 的预期工作。

更新

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

我也想在 Value 上应用它。

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

UPDATE2 - 答案

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

【问题讨论】:

  • 到底是什么问题?请记住,在 HashMap 中,键是散列的,而不是值
  • hashMap 如何调用 hascode & equals
  • Map 调用 equals 和 hashCode 方法,它正在这样做——对于 Integer 键!如果您希望 Map 检查 Employee hashCode 和/或等于,则 Employee 必须是 Key 而不是 Value。
  • 为什么即使 for key 重复也没有调用 hashMap(equals & hascode)。
  • 很高兴你已经弄明白了! 1+

标签: java hashmap


【解决方案1】:

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

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

我也想在 Value 上应用它

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

如果您希望在 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]

【讨论】:

  • @Ravi:如果 Employee 是 HashMap 的 key,你会看到 hashCode 方法被调用。请参阅我上面的编辑以了解 HashMap 如何调用 hashCode 和 equals。
  • 谢谢,我明白了,HashMap的key(class->hashCode)会被调用。
【解决方案2】:

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

【讨论】:

    【解决方案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);
      }
    

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

    【讨论】:

    • 我想覆盖 hashCode 和 Equals 但在 HashMap 'Equals & hashCode' 中没有覆盖。我也想把它应用到价值上
    • @Ravi:这毫无意义。 HashMap 工作正常。您只是不了解正在检查密钥。
    • 只是想确认一下 就像本例中HashSet调用equal和hashCode一样,为什么即使for key也没有调用hashMap。
    • e您提供的代码确实调用equalshashCode作为密钥,但密钥是Integers,而不是Employees。
    【解决方案4】:

    您使用的是HashMap&lt;Integer, Employee&gt;,看起来像,所以Integers 将被散列。由于键是1,2,3,4,5,所以HashMap 的大小应该是5。

    【讨论】:

    • 但运行时显示大小为 5
    猜你喜欢
    • 1970-01-01
    • 2014-04-03
    • 1970-01-01
    • 2020-02-09
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 2014-02-09
    • 2020-10-29
    相关资源
    最近更新 更多