HashMap使用equals true和相同的hashcode添加对象

vol*_* dr 4 java equals hashmap hashcode

我正在尝试为其创建自定义对象HashMap并编写代码hashcodeequals方法.在添加对象时HashMap,equals方法为true并且hashcode为两个对象返回相同的值,而HashMap将两个对象添加为不同的对象.这怎么可能?以下是我的代码:

class B {
    String name;
    int id;

    public B(String name, int id)
    {
        this.name=name;
        this.id=id;
    }

    public boolean equals(B b){
        if(this==b)
            return true;
        if(b==null)
            return false;
        if(this.name.equals(b.name) && this.id==b.id)
            return true;
        else
            return false;
    }

    public int hashcode(){
        return this.id;
    }

    public String toString(){
        return "name: "+name+" id: "+id;
    }
}
Run Code Online (Sandbox Code Playgroud)

为了测试上面的代码,我在我的主类中添加了以下内容:

HashMap<B,String> sample=new HashMap<>();
B b1 = new B("Volga",1);
B b2 = new B("Volga",1);
System.out.println(b1.equals(b2));
System.out.println(b1.hashcode()+"    "+b2.hashcode());
sample.put(b1, "wrog");
sample.put(b2,"wrog");
System.out.println(sample);
Run Code Online (Sandbox Code Playgroud)

这产生以下输出:

true
1    1
{name: Volga id: 1=wrog, name: Volga id: 1=wrog}
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么会这样吗?

tho*_*est 6

你有两个问题:

  1. 而不是实现equals(B)你应该实现equals(Object)(Javadoc)
  2. 它需要hashCode()代替hashcode()(Javadoc)

工作实现可能如下所示:

class B {
    String name;
    int id;

    public B(String name, int id) {
        this.name = name;
        this.id = id;
    }

    @Override
    public int hashCode() {
        return this.id;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        B other = (B) obj;
        if (id != other.id) {
            return false;
        }
        if (name == null) {
            if (other.name != null) {
                return false;
            }
        } else if (!name.equals(other.name)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "name: " + name + " id: " + id;
    }
}
Run Code Online (Sandbox Code Playgroud)

作为一般建议,请确保指定@Override注释.您的IDE和Java编译器(javac)可以帮助您发现这些问题.