Enumerating over Map#entrySet
doesn't work as expected for all Map implementations, specially for EnumMap, IdentityHashMap
and here is the sample code from Josh Bloch's puzzler presentation (Puzzle 5) -
public class Size {
private enum Sex { MALE, FEMALE }
public static void main(String[] args) {
printSize(new HashMap<Sex, Sex>());
printSize(new EnumMap<Sex, Sex>(Sex.class));
}
private static void printSize(Map<Sex, Sex> map) {
map.put(Sex.MALE, Sex.FEMALE);
map.put(Sex.FEMALE, Sex.MALE);
map.put(Sex.MALE, Sex.MALE);
map.put(Sex.FEMALE, Sex.FEMALE);
Set<Map.Entry<Sex, Sex>> set =
new HashSet<Map.Entry<Sex, Sex>>(map.entrySet());
System.out.println(set.size());
}
}
and yes that produces the wrong result -
supposed to be
2
2
but produces
2
1
but if I try with below code - it produces the correct result
UPDATE
Though the size of the resulting Set is 2 but Entries are same.
public class Test{
private enum Sex { MALE, FEMALE }
public static void main(String... args){
printSize(new HashMap<Sex, String>());
printSize(new EnumMap<Sex, String>(Sex.class));
}
private static void printSize(Map<Sex, String> map) {
map.put(Sex.MALE, "1");
map.put(Sex.FEMALE, "2");
map.put(Sex.MALE, "3");
map.put(Sex.FEMALE, "4");
Set<Map.Entry<Sex, String>> set =
new HashSet<Map.Entry<Sex, String>>(map.entrySet());
System.out.println(set.size());
}
}
I even tried the above code with the two different enum types as key and value.
This seems to be issue only if EnumMap has a same enum as a key and value.
I would like to know why is this? or I'm missing something.why it's not fixed when ConcurrentHashMap got fixed long back?