我有一个名为MyClass的课程:
public class MyClass extends abstractClass implements
someInterface {
Set<VNode> relation_;
Set<VNode> x_;
Set<VNode> y_;
@Override
public boolean equals(Object obj) {
if (!super.equals(obj)) {
return false;
}
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof MyClass)) {
return false;
}
MyClass other = (MyClass) obj;
if (relation_ == null) {
if (other.relation_ != null) {
return false;
}
} else if (!relation_.equals(other.relation_)) {
return false;
}
if (x_ == null) {
if (other.x_ != null) {
return false;
}
} else if (!x_.equals(other.x_)) {
return false;
}
if (y_ == null) {
if (other.y_ != null) {
return false;
}
} else if (!y_.equals(other.y_)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int res = new HashCodeBuilder(17, 37).append(relation_).append(x_)
.append(y_).append(getWeight()).toHashCode();
return res;
}
}
抽象类如下:
public abstract class abstractClass {
double weight_;
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof abstractClass)) {
return false;
}
abstractClass other = (abstractClass) obj;
if (Double.doubleToLongBits(weight_) != Double
.doubleToLongBits(other.weight_)) {
return false;
}
return true;
}
public double getWeight() {
return weight_;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(weight_);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
}
现在,如果我有HashSet<MyClass> s1
和MyClass i1
,即使s1
有一个s1i
元素s1i.equals(i1)=true
和s1i.hashCode()=i1.hashCode()
,{ {1}}给了我s1.contains(i1)
。
有任何解释吗?
其他课程:
false
答案 0 :(得分:2)
你的equals()方法根本不可读。由于您在hashCode()中使用HashCodeBuilder,为什么不使用EqualsBuilder呢?
版本a)
public boolean equals(Object obj){
if(obj == null || obj.getClass()!=getClass()){
return false;
}
MyClass other = (MyClass) obj;
return new EqualsBuilder()
// check parent properties first
.append(this.getWeight(), other.getWeight())
.append(this.relation_, other.relation_)
.append(this.x_, other.x_)
.append(this.y_, other.y_)
.isEquals();
}
版本b)
public boolean equals(Object obj){
// delegate to parent equals first
if(!super.equals(obj)){
return false;
}
MyClass other = (MyClass) obj;
return new EqualsBuilder()
.append(this.relation_, other.relation_)
.append(this.x_, other.x_)
.append(this.y_, other.y_)
.isEquals();
}
答案 1 :(得分:1)
在计算equals和hashcode时,每个类只应关注自己的变量。因此,在MyClass中而不是调用getWeight()
,您应该使用超类的哈希码。和你一样equals()
!在这种情况下,效果将是相同的。
public int hashCode() {
int res = new HashCodeBuilder(super.hashcode(), 37).append(relation_).append(x_)
.append(y_);
return res;
}
这意味着对可能影响equals和hashcode的基类的任何更改都局限于类,并且您不必更新子类。
(不是一个真正的答案,更多的是观察,但它的评论太大了)