Reputation: 12207
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
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