Issue
I have these two java classes as below:
RelocationDisabledProduct
public class RelocationDisabledProduct {
@JsonProperty("productIdentifierType")
private ProductIdentifierType productIdentifierType;
@JsonProperty("id")
private String id;
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null) {
return false;
}
final Item that = (Item)o;
return Objects.equals(id, that.getId()) &&
Objects.equals(productIdentifierType, that.getProductIdentifierType());
}
@Override
public int hashCode() {
return Objects.hash(id, productIdentifierType);
}
}
Item
public class Item {
private String id;
private ProductIdentifierType productIdentifierType;
}
equals works fine
relocationDisabledProduct.equals(item) // true
but contains does not
List<RelocationDisabledProduct> relocationDisabledProducts;
...
getRelocationDisabledProducts().contains(item) // false
Since contains uses the equals method, not sure why my above syntax returns false?
Solution
I believe this is due to the definition of AbstractCollection<E> contains(Object o)
. The Javadoc says
public boolean contains(Object o)
Returns true if this collection contains the specified element. More formally, returns true if and only if this collection contains at least one element e such that Objects.equals(o, e).
Note the order of arguments to contains()
. It is using the equals()
method from Item
, not the one from RelocationDisabledProduct
, which you would have probably seen if you stepped into the code in the debugger.
Both Item
and RelocationDisabledProduct
need to share a common equals()
implementation, maybe a default method of a superinterface... you'll have to work out what makes sense in your case.
Answered By - Jim Garrison
Answer Checked By - Katrina (JavaFixing Volunteer)