Java 为什么set.contains不使用重写的equals()方法?

Java 为什么set.contains不使用重写的equals()方法?,java,set,equals,contains,hashset,Java,Set,Equals,Contains,Hashset,我有一门课是这样的: 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+"

我有一门课是这样的:

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


非常感谢您的帮助。

您的类违反了
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));

正如@Sweeper所写的,您的hashCode应该以任何参数顺序返回相同的值,因此您可以返回参数的hashCode之和:

@Override
public int hashCode() {
    return Objects.hashCode(v) + Objects.hashCode(w);
}

你试过调试你的代码吗?
HashSet
集合。包含的
将通过
hashCode()
(首先)和你的顶点
v,w
w,v
进行比较。@elliotfrisch这很有意义,你知道如何让它们具有相同的hashCode吗?你可以尝试
返回v+w