我正在编写一些代码来演示 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/