2016-02-29 68 views
0

在我的java程序中,我有一個映射,其中包含someID和MyClass類型的數據對象之間的關聯。如何實現不對稱等於功能?

ConcurrentMap<Integer, MyClass> a; 

我不太經常但經常檢查一個「值」對象是否包含某個長變量b。由於我不知道將someId與其他Id相關聯,因此無法通過地圖訪問它。 要做到這一點,我想使用的containsValue:

a.containsValue(otherId) 

爲了實現這個目標我重寫了哈希碼和平等的功能。

@Override 
public boolean equals(Object o) { 
    if ((o instanceof MyClass) && (((MyClass) o).someId().equals(this.someId()))) { 
     return true; 
    } else 
    if ((o instanceof Long) && ((Long) o) == this.otherId) { 
     return true; 
    } else { 
     return false; 
    } 
} 

注意:代碼中的otherId不一定需要是地圖的someID。

第一個if語句是對稱的,第二個顯然不是。我明白,這不是很好,但每次寫一個循環也不好。 在this post他們說不對稱等於將被忽略。我如何讓java忽略不對稱問題?

+0

等於已被定義,在這種情況下,你不能是對稱其「忽略」的問題因爲你不能修改「長」類。如果你的鑰匙可以成爲「長」,那麼只需要長一點。 –

+0

儘可能地避免在Map上調用'containsValue',因爲它是一個'O(n)'操作。 –

回答

4

您使用的是Java-8,它是不是很難寫:

a.values().stream().anyMatch(myObj -> myObj.otherId() == wantedId); 
2

總之:不要試圖用equals()來做到這一點。該方法的合同是它應該是對稱的(以及自反性,傳遞性和其他一些屬性)。請參閱Javadoc瞭解equals所需屬性的完整說明。

Java API(更一般地說)中的類被實現以期望該屬性被保留,所以如果你故意違反合同,可能會意外地表現出來。

爲您的類添加一個明確用於測試此不對稱屬性的新類。 compareAssymetrically

2

的問題與您equals實現是一個Long例如lMyClass例如mm.equals(l)可能返回true,而l.equals(m)總是會返回false,因爲你不能改變Long的實施equals

如果您使用的是使用equalsArrayListHashMap,等...),你無法控制是否m.equals(l)l.equals(m)被稱爲任何類,所以,只要你想它表現你的代碼可能無法正常使用。

如果你想檢查是否Long「等於」到MyClass例如,創建一個MyClass實例,它的otherId等於Long,並比較這兩個MyClass實例。

@Override 
public boolean equals(Object o) { 
    if (o instanceof MyClass) { 
     MyClass m = (MyClass) o; 
     if (m.someId().equals(this.someId())) { 
      return true; 
     } else if (m.otherId == this.otherId) { 
      return true; 
     } else { 
      return false; 
     } 
    } 
    return false; 
} 

public boolean equals(Long l) { 
    MyClass m = new MyClass(); 
    m.setOtherId(l); 
    return equals(m); 
} 
+0

我相信你的答案在技術上是對我的問題和走向的正確答案。我接受了塔吉爾的回答,因爲那正是我現在使用的。 – Jochen