I have two methods, the first needs a Map<ItemA, ItemB> the second a Map<ItemA ,ItemB[]>. How can I create a generic Map that covers both cases?
4 Answers
You cannot. How is this going to work? If the first method does a map.get(key) and gets an ItemB[] instead of an ItemB, it'll complain with a ClassCastException.
The whole point of generic collections is to separate these two cases.
You could make a wrapper that wraps a Map<ItemA, ItemB> as a Map<ItemA, ItemB[]>, returning an array with just one element for everything. But this may cause trouble with array manipulation semantics.
Maybe just copy everything:
// upgrade from Map to MultiMap
HashMap<ItemA, ItemB[]> map1Copy = new HashMap<ItemA, ItemB[]>(map1.size());
for (Entry<ItemA, ItemB> e: map1.entrySet()){
map1Copy.put(e.getKey(), new ItemB[]{ e.getValue()});
}
The other direction (converting ItemB[] into a single ItemB) does not work in general.
1 Comment
The best you can do is a Map<ItemA, ?>, I think. ItemB and ItemB[] are pretty much unrelated in terms of the type hierarchy.
You'd then have to use instanceof or something to figure out which was which and handle them separately. So you might as well not bother and have separate methods for ItemB and ItemB[] :)
Comments
If you really want to do it and don't have any special reason for using arrays instead of lists I suggest create a Map> map and handle the different cases; with only one element in the list or more than one element. But as other people pointed out it seems like its two different cases and should be two different maps.