【问题标题】:Custom object as Map key自定义对象作为 Map 键
【发布时间】:2019-09-13 18:58:36
【问题描述】:

正如我所读到的,如果自定义对象需要成为 map 的键,则需要覆盖 hashcode 和 equals 方法,但在我的情况下,它可以在不覆盖它的情况下工作。有人可以告诉我出了什么问题吗?

    Map<Student,Integer> map = new HashMap<>();
    Student s1=new Student(1,"A");
    Student s2=new Student(2,"B");
    Student s3=new Student(3,"C");

    map.put(s1,1);
    map.put(s2,2);
    map.put(s1,3);

    for(Student s:map.keySet()) {
        System.out.println(map.get(s) + "->" + s.id + " " +s.name);
    }

正确的输出:

3-> 1A

2-> 2 B

【问题讨论】:

  • 您正在重用同一个对象。 map.put(s1,1)map.put(s1,3); 所以 s1.equals(s1) 始终为真,即使没有覆盖 equals 方法
  • 如果你想实例化两个相似的Student对象并让它们被视为相等,那么你需要重写equals和hashCode。
  • 谢谢@AntonBalaniuc
  • 谢谢@khelwood

标签: java collections hashmap equals hashcode


【解决方案1】:

它是equals 方法的properties 之一:它是自反的。这意味着

x.equals(x) == true 

一个对象总是等于它自己。在这种情况下,您将中继 equals 方法的默认实现。

map.put(s1,1); 
map.put(s1,3);

因为默认实现是自反的

s1.equals(s1) == true 

1 替换为3

但是,如果你这样做,结果会有所不同

map.put(new Student(1,"A"),3);

s1.equals(new Student(1,"A")); 

您需要覆盖hashCodeequals 才能使其正常工作。

【讨论】:

    【解决方案2】:

    如果没有覆盖的 hashCode 和 equals 方法,Java 会比较对象引用。因此,s1 引用与 s1 引用相同,因此您可以将 s1 关联值替换为另一个。

    如果您创建一个新的Student 对象,其属性值与s1 相同,并尝试将其插入到您的地图中,您将拥有两个不同的对。

    【讨论】:

      【解决方案3】:

      内置 hashCode()equals() 工作正常。它们与HashMap 要求的方式一致(即:如果hashCode()s 不相同,equals() 将始终返回false)。那是因为每个对象实例都只会是equal()

      但是,这通常不是您想要的。具体来说,如果不覆盖这些方法,两个具有相同字段的Student 实例将不被视为相等。所以这将打印出三行而不是一行:

      Map<Student,Integer> map = new HashMap<>();
      Student s1=new Student(1,"A");
      Student s2=new Student(1,"A");
      Student s3=new Student(1,"A");
      
      map.put(s1,1);
      map.put(s2,2);
      map.put(s3,3);
      
      for(Student s:map.keySet()) {
          System.out.println(map.get(s) + "->" + s.id + " " +s.name);
      }
      

      (注意:从技术上讲,这完全正确,但不一定是大多数阅读您的代码的人所期望的。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-23
        • 2011-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多