java - 哈希码和等于实现

标签 java comparison equals hashcode apache-commons-lang

我正在编写一些代码来演示 equals 和 hashcode,对于我的实现,我使用了用户示例:

public class User {
    private String name;
    private String pass;
    //...
    @Override
    public boolean equals(Object obj) {
        if (obj == null) { return false; }
        if (obj == this) { return true; }
        if (obj.getClass() != this.getClass()) {
            return false;
        }
        User rhs = (User) obj;

        EqualsBuilder eb = new EqualsBuilder();
        eb.append(this.getName(), rhs.getName());
        //eb.append(this.getPass(), rhs.getPass());
        return eb.isEquals();
    }
    @Override
    public int hashCode() {
        HashCodeBuilder hcb = new HashCodeBuilder(17, 37);
        hcb.append(this.getName());
        hcb.append(this.getPass());
        return hcb.toHashCode();
    }
    //...
    public static void main(String[] args) {

        User u1 = new User("foo","foo1");
        User u2 = new User("bar","bar1");
        System.out.println(u1.equals(u2));
        System.out.println(u1.hashCode() + " ?= " + u2.hashCode());
        User u3 = new User("foo","foo1");
        User u4 = new User("foo","bar1");
        System.out.println(u3.equals(u4));
        System.out.println(u3.hashCode() + " ?= " + u4.hashCode());

    }
}

输出:

false
2128613651 ?= 2129111967
true
2128615478 ?= 2214545177

我认为我做错了,因为我的对象现在可以相等但具有不同的哈希码(我知道这很糟糕),但我想让我的用户只有在他们的名字也相等时才相等......而不是当他们有名字并传递等于时。

怎样才能尊重约定俗成,达到自己想要的效果? 感谢您的帮助/澄清:)

最佳答案

一般来说,如果您的 equals() 方法中不存在某个字段,则不应在您的 hashCode() 方法中引用它。

这确保您的 hashcode() 结果不会比您的 equals() 结果更改得更频繁。考虑将您的方法更改为:

@Override
public int hashCode() {
    HashCodeBuilder hcb = new HashCodeBuilder(17, 37);
    hcb.append(this.getName());
    return hcb.toHashCode();
}

话虽如此,创建非直观的 equals() 方法很少是个好主意。我自然会假设您的方法也会考虑密码,就像您 future 的许多维护者一样。如果不进行真正的相等性测试,单元测试可能更难编写。考虑创建自己的方法是否更好,例如

public boolean usernameEquals(User other) {
  ...
}

关于java - 哈希码和等于实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25261069/

相关文章:

java - 如何在 CXF 的 READ 阶段从 SoapMessage 中提取请求的操作名称?

java - 在java中,只有鼠标悬停在按钮上才会显示按钮

comparison - 为什么有这么多方法来比较是否相等?

python - 获取python中2个数据帧之间的差异数

python - 如何比较 python 自定义类中 None 对象的相等性?

java - 如何解决运行jar文件时出现 "Could not find or load main class"问题

java - FirebaseRecyclerAdapter 无法工作或显示任何数据

java - 多个单词的字符串比较

java - 如何检查注释的相等性?

c# - 通用函数中的 equals() 和 ==