[英]Find a value of a map with the inverse key
我目前有一張具有以下值的地圖:
private static final Map<Entrie, somePOJO> MAP = new ConcurrentHashMap<>();
static {
MAP.put(Object.of(A.class, B.class), new someOtherClass());
}
該 Object 類是我創建的一個類,用於模擬鍵值關系。
我想要做的是通過搜索反向鍵來獲取 someOtherClass 的實例。
示例:MAP.get(Object.of(B.getClass, A.getCall)) 應該返回新的 someOtherClass 的實例,但它按預期返回 null,因為沒有像我正在搜索的鍵那樣的鍵。
有關如何解決問題的任何提示?
考慮使鍵類型無序。 例如使用散列集。 然后 A>B 和 B>A 對變得相等,並且將被視為地圖的相同鍵。
MAP.put(Set.of(A.class, B.class), new someOtherClass());
MAP.get(Set.of(B.class, A.class)); // will return the new someOtherClass()
聽起來您希望Object.of("A", "B")
和Object.of("B", "A")
都被視為完全相同的鍵 - 只有一個對象可以是與其中任何一個關聯,並使用其中一個作為參數來映射的get
調用返回與它們關聯的對象。
您有兩個選擇:
映射實現使用某個“相等函數”來確定鍵是否被認為是相等的。
大多數使用 equals 和 hashCode,我將介紹。 兩個主要的替代方案是TreeMap
,它使用您在構造函數中提供的比較器(如果您不提供,則 Key 類型必須是Comparable
,並且將使用它的 compareTo 方法)。 它完全忽略了equals
和hashCode
。 另一個是WeakHashMap
,它使用對象標識,在這里完全沒用。
幾乎所有其他內容(例如java.util.HashMap
)都通過調用鍵對象的equals
和hashCode
方法來確定相等性。 規則是:
a.equals(b)
的結果必須與b.equals(a)
相同a.equals(a)
必須返回 true。equals
不能拋出任何異常。a.equals(b)
,則a.hashCode()
必須等於b.hashCode()
,但反過來不一定成立:如果a.hashCode()
與b.hashCode()
相同,則它們不需要是a.equals(b)
,在那種情況下(相同的哈希碼,但不相等),它們......只是不相等。 但是,如果它們相等,則它們必須具有相同的哈希碼,否則映射將不起作用。 是的, return 1;
是hashCode()
的技術上合法的實現 鑒於所有這些,您需要發明的是hashCode()
和equals(Object)
方法的實現,例如Object.of("A", "B")
和Object.of("B", "A")
是平等的。 對於散列碼,您可以散列每個單獨的值並將它們異或在一起,因為異或關系是可交換的: a^b^c
與c^a^b
結果相同 - 順序無關緊要。 為了平等,好吧,你是一個程序員,編寫一個算法。 一種簡單而快速的方法是將所有元素扔到一個TreeSet
,即將所有元素存儲在自排序數據結構中,從而保證具有相同元素的該結構的任何版本都必須以相同的順序排列,從而使等式變得微不足道.
然后另一種選擇是使用TreeMap
(但請注意,這意味着地圖的內容將根據比較器進行排序),使用采用Comparator<YourObj>
的構造函數之一。 然后規則變成:
comparator.compare(a, a)
必須返回0
comparator.compare(a, b)
需要匹配comparator.compare(b, a)
:如果一個返回 0,另一個也必須。 如果一個返回一個正數,另一個必須返回一個負數。comparator.compare(a, b)
為0,則認為這2 個對象相等。 因此,工作就變成確保比較Object.of("A", "B")
和Object.of("B", "A")
返回 0。在這種安排中沒有 hashCode 函數,所以你只需要要做的就是實現這一點,但是如果它們不相等,您不能隨意返回-1
或+1
,它必須是一致的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.