簡體   English   中英

java.util.HashSet不遵守其規范嗎?

[英]Does java.util.HashSet not Adhere to its Specification?

作為一個相對的Java菜鳥,我很困惑,找出以下內容:

Point.java:

public class Point {
...
    public boolean equals(Point other) {
        return x == other.x && y == other.y;
    }
...
}

Edge.java:

public class Edge {
    public final Point a, b;
    ...
    public boolean equals(Edge other) {
        return a.equals(other.a) && b.equals(other.b);
    }
...
}

main snippet:private Set blockedEdges;

public Program(...) {
    ...
    blockedEdges = new HashSet<Edge>();

    for (int i = 0; ...) {
        for (int j = 0; ...) {

            Point p = new Point(i, j);              
            for (Point q : p.neighbours()) {

                Edge e = new Edge(p, q);
                Edge f = new Edge(p, q);

                blockedEdges.add(e);


                // output for each line is: 
                // contains e? true; e equals f? true; contains f? false

                System.out.println("blocked edge from "+p+"to " + q+
                      "; contains e? " + blockedEdges.contains(e)+
                      " e equals f? "+ f.equals(e) + 
                      "; contains f? " + blockedEdges.contains(f));
            }
        }
    }
}

為什么這令人驚訝? 因為我在編碼之前檢查了文檔以依賴於相等性,它

如果此set包含指定的元素,則返回true。 更正式地,當且僅當此集合包含元素e時才返回true(o == null?e == null:o.equals(e))

這句話非常清楚,它表明只需要平等。 f.equals(e)返回true,如輸出中所示。 很明顯,集合確實包含元素e,使得o.equals(e),但包含(o)返回false。

雖然哈希集也取決於哈希值是否相同,這當然是可以理解的,但是在HashSet本身的文檔中既沒有提到這個事實,也沒有在Set的文檔中提到任何這樣的可能性。

因此,HashSet不符合其規范。 這看起來像是一個非常嚴重的錯誤。 我在這里走錯了路嗎? 或者接受這樣的行為怎么樣?

你沒有壓倒equals (你正在超載它)。 equals需要接受一個Object作為參數。

做點什么

@Override
public boolean equals(Object o) {
    if (!(o instanceof Point))
        return false;
    Point other = (Point) o;
    return x == other.x && y == other.y;
}

(和Edge

當你重寫equals時,總是覆蓋hashCode也很重要。 請參閱例如為什么我需要覆蓋Java中的equals和hashCode方法?

請注意,如果您使用了@Override ,則編譯會捕獲此錯誤。 這就是為什么在可能的情況下始終使用它的好習慣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM