I have a HashMap for storing objects:
private Map<T, U> fields = Collections.synchronizedMap(new HashMap<T, U>());
but, when trying to check existence of a key, containsKey
method returns false
.equals
and hashCode
methods are implemented, but the key is not found.
When debugging a piece of code:
return fields.containsKey(bean) && fields.get(bean).isChecked();
I have:
bean.hashCode() = 1979946475 fields.keySet().iterator().next().hashCode() = 1979946475 bean.equals(fields.keySet().iterator().next())= true fields.keySet().iterator().next().equals(bean) = true
but
fields.containsKey(bean) = false
What could cause such strange behavioure?
public class Address extends DtoImpl<Long, Long> implements Serializable{ <fields> <getters and setters> @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + StringUtils.trimToEmpty(street).hashCode(); result = prime * result + StringUtils.trimToEmpty(town).hashCode(); result = prime * result + StringUtils.trimToEmpty(code).hashCode(); result = prime * result + ((country == null) ? 0 : country.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Address other = (Address) obj; if (!StringUtils.trimToEmpty(street).equals(StringUtils.trimToEmpty(other.getStreet()))) return false; if (!StringUtils.trimToEmpty(town).equals(StringUtils.trimToEmpty(other.getTown()))) return false; if (!StringUtils.trimToEmpty(code).equals(StringUtils.trimToEmpty(other.getCode()))) return false; if (country == null) { if (other.country != null) return false; } else if (!country.equals(other.country)) return false; return true; } }
Return Value: The method returns boolean true if the presence of the key is detected else false .
containsKey() method is used to check whether a particular key is being mapped into the Map or not. It takes the key element as a parameter and returns True if that element is mapped in the map.
get(Object) does explicitly warn about the subtle differences between Map. get(Object) and Map. containsKey(Object) : If this map permits null values, then a return value of null does not necessarily indicate that the map contains no mapping for the key; it's also possible that the map explicitly maps the key to null .
This implementation provides constant-time performance for the basic operations (get and put), assuming the hash function disperses the elements properly among the buckets. Since containsKey() is just a get() that throws away the retrieved value, it's O(1) (assuming the hash function works properly, again).
You shall not modify the key after having inserted it in the map.
Edit : I found the extract of javadoc in Map :
Note: great care must be exercised if mutable objects are used as map keys. The behavior of a map is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is a key in the map.
Example with a simple wrapper class:
public static class MyWrapper { private int i; public MyWrapper(int i) { this.i = i; } public void setI(int i) { this.i = i; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; return i == ((MyWrapper) o).i; } @Override public int hashCode() { return i; } }
and the test :
public static void main(String[] args) throws Exception { Map<MyWrapper, String> map = new HashMap<MyWrapper, String>(); MyWrapper wrapper = new MyWrapper(1); map.put(wrapper, "hello"); System.out.println(map.containsKey(wrapper)); wrapper.setI(2); System.out.println(map.containsKey(wrapper)); }
Output :
true false
Note : If you dont override hashcode() then you will get true only
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With