我有一个这样的班级:
class Vertex {
char v;
char w;
int cost;
public Vertex(char v, char w, int cost){
this.v = v;
this.w = w;
this.cost = cost;
}
@Override
public String toString(){
return "["+v+" "+w+" "+cost+"]";
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Vertex vertex = (Vertex) o;
return (v == vertex.v && w == vertex.w) || (w == vertex.v && v == vertex.w);
}
@Override
public int hashCode() {
return Objects.hash(v, w);
}
}
当两个顶点相等或相反时,我试图让equals()
返回true。意味着如果有一个顶点(v,w)和(w,v),它应该返回true。
我的equals()
是对称且自反的,但是set.contains()
对于(v,w)和(w,v)情况仍然返回false。
我将不胜感激。
答案 0 :(得分:1)
您的课程违反了hashCode()
而不是equals()
的一般合同。 Set.contains()
使用hashCode()
达到O(1)时间。
hashCode()
的一般约定规定,相等的对象必须具有相等的哈希码。但是,在您的情况下,[v=1, w=2]
和[v=2, w=1]
被认为是相等的,但是它们具有不同的哈希码。您将分别呼叫Objects.hash(1, 2)
和Objects.hash(2, 1)
。
您应该更改哈希代码实现,使其独立于v
和w
的顺序。一种方法是先对较小的哈希进行哈希处理:
return Objects.hash(Math.min(v, w), Math.max(v, w));
答案 1 :(得分:1)
正如@Sweeper所写,您的hashCode应该以任何参数顺序返回相同的值,因此您可以返回参数的hashCode之和:
@Override
public int hashCode() {
return Objects.hashCode(v) + Objects.hashCode(w);
}