Konrad Höffner
Konrad Höffner

Reputation: 12207

Java Set of Maps hashCode incorrect?

I am getting unexpected results from a Set of Maps (Set<Map<String,String>>), where s.contains(s.iterator().next()) is false.

The set in question contains only one map that is [{=262.666666666666667}] (the empty String mapped to the String 262.666666666666667).

I have been unable to put together a minimal working example that replicates the problem as the following outputs true:

Set s = new HashSet<Map<String,String>>();
Map<String,String> m = new HashMap<>();
m.put("", "262.666666666666667");
s.add(m);
System.out.println(s.contains(s.iterator().next()));

HashMap does not override hashCode but Abstract map does (see below) so I don't see the problem of putting a HashMap in a HashSet.

public int hashCode()
{
     int h = 0;
     Iterator<Entry<K,V>> i = entrySet().iterator();
     while (i.hasNext())
         h += i.next().hashCode();
     return h;
}

What is the reason for this behaviour and how can I fix it?

Edit: Thanks at doublep and morgano, I indeed modified the map after adding it and resolved the issue by adding after the modification instead of before.

Upvotes: 1

Views: 143

Answers (1)

morgano
morgano

Reputation: 17422

If you want to reproduce the error, modify your code in this way:

    Set s = new HashSet<Map<String,String>>();
    Map<String,String> m = new HashMap<>();
    s.add(m);
    m.put("", "262.666666666666667");
    System.out.println(s.contains(s.iterator().next()));

That is, add the map to the set and then put a new key/value in the map.

The problem is that, as you said, Abstract map overrides equals() to depend on the key/values that the map holds at that moment. Set uses internally a Map, being the key the value of equals() at the moment your Map is being added to the set. When you add a new key/value to your Map then the value returned by equals() also changes and doesn't correspond to the original value, this way you get false for System.out.println(s.contains(s.iterator().next()));

Upvotes: 3

Related Questions