簡體   English   中英

TreeMap put沒有按預期工作

[英]TreeMap put is not working as expected

class Point{
    int x, y, l;

    Point(int x, int y, int l){
        this.x =x;
        this.y =y;
        this.l=l;
    }
    @Override
    public int hashCode() {
        return y;
    }

    @Override
    public boolean equals(final Object obj) {
        if(this == obj) return true;
        if(!(obj instanceof Point)) return false;
        Point p = (Point) obj;
        return this.x == p.x && this.y == p.y;
    }
}

    TreeMap<Point,Integer>  sortedMap = new TreeMap<>((p1, p2)-> p1.l-p2.l);
    sortedMap.put(new Point(4,5,0),0);
    sortedMap.put(new Point(5,5,0),6);
    System.out.println(sortedMap.size()); -> Output:  1
    System.out.println((new Point(4,5,0)).equals(new Point(5,5,0))); -> Output -> False.

我在類中重載了hashcode,equals方法。 我認為put方法應該使用equals方法來確定是否退出相同的對象。 但它沒有按預期工作。

我不知道為什么我的hashMap大小為1.如果我理解hashmap錯誤地工作,請告訴我。 幫我識別一下這段代碼中的錯誤?

你的TreeMap正在通過l部分比較Point值(不管是什么意思)。 這就是你的代碼的這一部分:

new TreeMap<>((p1, p2)-> p1.l-p2.l);

您創建的兩個點具有相同的l值(0),因此它們被視為相等...因此第二次調用put將替換現有條目。 TreeMap根本不使用equalshashCode

文檔

請注意,如果此有序映射要正確實現Map接口,則樹映射維護的順序(如任何有序映射)以及是否提供顯式比較器必須與equals一致。 (有關與equals一致的精確定義,請參見Comparable或Comparator。)這是因為Map接口是根據equals操作定義的,但是有序映射使用compareTo(或compare)方法執行所有鍵比較,因此從排序映射的角度來看,通過此方法被視為相等的鍵是相等的。 即使排序與equals不一致,也可以很好地定義有序映射的行為。 它只是不遵守Map接口的一般合同。

您的比較並非一致equals ,這就是為什么你看到違反結果Map的合同。

TreeMap僅使用提供的Comparator (或可用​​時的自然順序)來確定相等性,因此equalshashCode沒有區別。

在您的情況下,兩個Point都具有相同的l值,因此根據您的Comparator ,它們被認為是相同的。

在確定鍵的順序(和相等)時,可以修改Comparator以將所有屬性( lxy )考慮在內。

sortedSet.put(new Point(4,5,0),0);
sortedSet.put(new Point(5,5,0),6);

這些put調用使用提供的比較器((p1, p2)-> p1.l-p2.l)來檢查兩個Point是否equal

(new Point(4,5,0)).equals(new Point(5,5,0))

這使用了Point類中的equals重寫。

因此差異..

暫無
暫無

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

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