Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java HashMap containsKey returns false for existing object

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; }   } 
like image 721
agad Avatar asked Feb 06 '14 10:02

agad


People also ask

What is the return type of containsKey () function in HashMap?

Return Value: The method returns boolean true if the presence of the key is detected else false .

What does containsKey return?

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.

What is the significant difference between containsKey () and get ()?

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 .

Why is HashMap containsKey O 1?

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).


1 Answers

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

like image 169
Arnaud Denoyelle Avatar answered Oct 03 '22 01:10

Arnaud Denoyelle