重写的等于和hashCode不适用于自定义Object



我有一个下面的对象

class CustomObj{
private String name;
private String dept;
public String getName(){
return this.name;
}
public String getDept(){
return this.dept;
}
private CustomObj(){
}
private CustomObj(CustomObjBuilder builder){
this.name = builder.name;
this.dept= builder.dept;
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (o == null || getClass() != o.getClass()) return false;
CustomObj that = (CustomObj) o;
return that.name.equals(name) &&
that.dept.equals(dept);
}
@Override
public int hashCode() {
int result = 31;
result = 31 * result + name.hashCode();
result = 31 * result + dept.hashCode();
return result;
}
public static class CustomObjBuilder{
private String name;
private  String dept;

public CustomObjBuilder(String name, String dept){
this.name = name;
this.dept = dept;
}
public CustomObjBuilder setName(String name){
this.name = name;
return this;
}
public CustomObjBuilder setDept(String dept){
this.dept = dept;
return this;
}
public CustomObj build(){
return new CustomObj(this);
}
}
}

以及使用以上的类

class XYZ{
Set<CustomObj> obj = new HashSet<CustomObj>();
public void process(String a, String b){
CustomObj o = new CustomObj.CustomObjBuilder(a,b).build();
if(!obj.contains(o)){
obj.add(o);
} 
}
}

和一个测试类

class TestXYX{
@Test
public void test(){
XYZ xyz = new XYZ();
xyz.process("TEST","TESTABC");
xyz.process("TEST","TESTABC");
}
}

因为我已经覆盖了hascode和equals,所以上面两个都是相等的,当第二次调用进程时,控件不应该第二次进入if(!obj.contains(o)),集合的大小应该是1。但是当我运行测试时,obj.add(o);被调用了两次。但是equals方法中的这个对象和那个对象的值是相同的,但是

that.name.equals(name) && that.dept.equals(dept)

内部CustomObj返回false。有人能帮我理解为什么吗?

代码很好。要验证,请添加sysout以检查Set大小:

class XYZ {
Set<CustomObj> obj = new HashSet<CustomObj>();
public void process(String a, String b) {
CustomObj o = new CustomObj.CustomObjBuilder(a, b).build();
if (!obj.contains(o)) {         // Fails second time for your use case.
obj.add(o);
}
System.out.println(obj.size());  // This is 1 in your use case.
}
}

最新更新