簡體   English   中英

哈希碼和等於對象引用?

[英]Hashcode and Equals for object reference?

我有一個小眾的需求,需要鎖定兩個通用類型XY對象,並使用該對象返回類型T 我想將這些項目放在嚴格管理的HashMap並使用它來查找X,Y鍵。

但是,如何確保XY進行哈希編碼並在其內存引用上進行比較,而不是hashCode / equals的任何替代實現?

public final class BiReferenceCache<X,Y,T> { 
    private final HashMap<Key<X,Y>,T> cacheMap = new HashMap<>();

    public T get(X item1, Y item2) { 
        return cacheMap.get(new Key<X,Y>());
    }

    private static final class Key<X,Y> { 
        private final X val1;
        private final Y val2;

        Key(X val1, Y val2) { 
            this.val1 = val1;
            this.val2 = val2;
        }

        public int hashCode() { 
            //??? What do I do to hashcode by val1 and val2's memory reference?
        }
        public boolean equals(Object obj) { 
            //??? What do I do to check equality for val1 and val2's memory reference?
        }
    }

}

采用

System.identityHashCode

==

您可以使用==來檢查內存標識,並可以使用java.lang.System#identityHashCode(Object)來獲取不可覆蓋的哈希碼。

private static final class Key<X,Y> { 
    private final X val1;
    private final Y val2;

    Key(X val1, Y val2) { 
        this.val1 = val1;
        this.val2 = val2;
    }

    public int hashCode() { 
        return 31 * System.identityHashCode(val1) + System.identityHashCode(val2);
    }

    public boolean equals(Object obj) { 
        if (obj == null) {
            return false;
        }
        if (!obj instanceof Key) {
            return false;
        }
        Key other = (Key)obj;
        return val1 == other.val1 && val2 == other.val2;
    }
}

==運算符不應該斷言引用相等嗎?

這個問題可能會解決您對hashCode的關注: 當toString()和hashCode()被覆蓋時,如何獲取Java對象的“對象引用”? (在下面引用)

您打算如何計划使用它(您想做什么與需要調用的內容有所不同)?

在Javadocs中定義的hashCode()表示:

在合理可行的范圍內,由Object類定義的hashCode方法確實為不同的對象返回不同的整數。 (通常通過將對象的內部地址轉換為整數來實現,但是JavaTM編程語言不需要此實現技術。)

因此,如果您使用hashCode查明它是否是內存中的唯一對象,那么這樣做不是一個好方法。

System.identityHashCode執行以下操作:

無論給定對象的類是否覆蓋hashCode(),都為給定對象返回與默認方法hashCode()返回的哈希碼相同的哈希碼。 空引用的哈希碼為零。

對於您正在執行的操作,聽起來聽起來像您想要的...但是根據庫的實現方式,您想要執行的操作可能並不安全。

您應該將其用於hashCode:

val1.hashCode() + val2.hashCode();

並且等於:

val1.equals(obj.val1) && val2.equals(obj.val2);

基本上轉嫁責任。

PS:如果允許為null,則必須添加適當的代碼。

對於hashCode(),您可以簡單地使用:val1.hashCode()^ val2hashCode(); (按字節XOR運算符^)-不是一個很好的解決方案,但是可以做到。

在equals()中,您應該首先檢查兩個對象是否具有相同的引用(帶有==),然后檢查要比較的對象是否不為null。 之后,確保兩個對象都是相同類型的實例。 最后一步:檢查兩者的屬性值是否相等。

如果您有一個超類,則處理超類的前3個步驟將被視為一種好樣式。

暫無
暫無

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

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