Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HashMap / TreeSet combination inconsistency

This works ok:

Map aMap;
aMap = new HashMap<String, TreeSet<String>>();

This does not compile:

Map<String, Set<String>> aMap;
aMap = new HashMap<String, TreeSet<String>>();

Error message:

Compilation failed (26/05/2014 11:45:43) Error: line 2 - incompatible types - 
  found java.util.HashMap<java.lang.String,java.util.TreeSet<java.lang.String>>
  but expected java.util.Map<java.lang.String,java.util.Set<java.lang.String>>

Why?

like image 562
whytheq Avatar asked May 26 '14 10:05

whytheq


3 Answers

The first one works because you use a raw type (without generic) so you can put any type of map in there.

The second one doesn't work because a XXX<Set> is not a XXX<TreeSet>.

So you need to choose between:

Map<String, Set<String>> aMap = new HashMap<String, Set<String>>();
//or
Map<String, TreeSet<String>> aMap = new HashMap<String, TreeSet<String>>();

And in both case you will be able to write:

aMap.put("abc", new TreeSet<>());

The main difference is when you get an item from the map, with the former construct you won't have access to the TreeSet specific methods.

Finally, with Java 7+ you can omit the generic information on the right hand side and the compiler will determine it automatically for you:

Map<String, Set<String>> aMap = new HashMap<>();
Map<String, TreeSet<String>> aMap = new HashMap<>();
like image 91
assylias Avatar answered Nov 16 '22 13:11

assylias


Use this instead:

    Map<String, ? extends Set<String>> aMap;
    aMap = new HashMap<String, TreeSet<String>>();

Because the Set's generic must not be the same than TreeSet's generic.

like image 3
Grim Avatar answered Nov 16 '22 15:11

Grim


enter image description here

+1 to Peter's answer, TreeSet implements SortedSet which extends Set.

Map<String, ? extends Set<String>> aMap;
    aMap = new HashMap<String, TreeSet<String>>();

will work fine.

like image 3
underdog Avatar answered Nov 16 '22 15:11

underdog