【问题标题】:Why the output changes if we change the return value of equals method?如果我们改变 equals 方法的返回值,为什么输出会改变?
【发布时间】:2017-02-09 13:27:33
【问题描述】:
package com.sample;

import java.util.HashMap;

class Student{
    int id;

    @Override
    public int hashCode() {
        return -1;
    }

    @Override
    public boolean equals(Object obj) {
        return false; // returning false
    }

}

public class MainClass {

    public static void main(String[] args) {
        Student s1=new Student();
        s1.id=123;
        Student s2=new Student();
        s2.id=456;

        HashMap<Student,String> s=new HashMap<Student,String>();


        s.put(s1, "One");
        System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode());
        s.put(s2, "Two");
        System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode());
        s.put(s1, "Three");
        System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode());

        System.out.println("after insert");

        System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode());
        System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode());


    }

}



OUTPUT

 < s1 value > One < s1 hashcode > 79430
 < s2 value > Two < s2 hashcode > 84524
 < s1 value > Three < s1 hashcode > 80786814
after insert
 < s1 value > Three < s1 hashcode > 80786814 //printing three for s1
 < s2 value > Two < s2 hashcode > 84524 //printing two for s2

// 现在,如果我们将 equals 方法的返回类型更改为 true ,则输出会发生变化,并且两者都返回三个作为输出。如果我们更改 equals 方法的返回类型,我无法理解为什么输出会发生变化。请结合bucket(HashMap)和equals方法的上下文进行说明。

class Student{
    int id;

    @Override
    public int hashCode() {
        return -1;
    }

    @Override
    public boolean equals(Object obj) {
        return true; //returning true
    }

}

public class MainClass {

    public static void main(String[] args) {
        Student s1=new Student();
        s1.id=123;
        Student s2=new Student();
        s2.id=456;

        HashMap<Student,String> s=new HashMap<Student,String>();


        s.put(s1, "One");
        System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode());
        s.put(s2, "Two");
        System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode());
        s.put(s1, "Three");
        System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode());

        System.out.println("after insert");

        System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode());
        System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode());


    }

}


OUTPUT-

 < s1 value > One < s1 hashcode > 79430
 < s2 value > Two < s2 hashcode > 84524
 < s1 value > Three < s1 hashcode > 80786814
after insert
 < s1 value > Three < s1 hashcode > 80786814 //printing three for s1
 < s2 value > Three < s2 hashcode > 80786814 //printing three for s2

【问题讨论】:

标签: java hash hashmap overriding equals


【解决方案1】:

在您的第一个 sn-p 中,您的 equals 方法总是返回 false,这意味着 HashMap 认为所有 Student 实例都是唯一的。因此s.get(s1)s.get(s2) 返回不同的值。

在您的第二个 sn-p 中,您的 equals 方法始终返回 true 并且您的 hashCode 始终返回 -1,这意味着 HashMap 认为所有 Student 实例都是相同的。因此s.get(s1)s.get(s2) 都返回相同的值(每次调用put 都会覆盖之前的值)。该值为“三”,因为这是您在地图中输入的最后一个值(通过调用s.put(s1, "Three");)。

顺便说一句,我最初很惊讶你的第一个 sn-p 在所有对s.get() 的调用中都没有返回null,因为equals 总是返回false,所以HashMap 不应该能够找到给定键的key,即equal。但是,查看HashMap的源代码,我发现在调用equals之前,首先将密钥与==进行比较,这就是HashMap可以找到您的密钥的原因。

【讨论】:

  • 嗨,Eran,我有一个疑问,在第一个 sn-p 中,当 equals 方法返回 false 时。首先,当我们执行 s.put(s1, "One") 时,这会将值存储在 HashMap 中,但是当我们执行 s.put(s1, "Three") 时,为什么要替换值和不抛出异常?
  • 据我了解,当我们使用,s.put(s1, "Three")时,它会对key进行hash并获取bucket索引并将值存储在该索引处。现在当我们执行 s.put(s1, "Three") 时,它会对 key 执行 hasing 并获取桶索引,它将 key 与该索引处的条目进行比较,然后它总是返回 false 作为 equals 方法每次都被覆盖以返回 false。所以它应该有一个更多的条目,但是有一个具有相同键的条目会违反 hashmap 属性,这就是它应该返回错误的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
  • 2013-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多