3

I want to have a function which (for example) outputs all the values of a Map in both cases:

Map<String, String> map1 = new HashMap<String, String>();
Map<String, Integer> map2 = new HashMap<String, Integer>();
output(map1, "1234");
output(map2, "4321");

And the following doesn't seem to work:

public void output(Map<String, Object> map, String key) {
    System.out.println(map.get(key).toString()); 
}

Are not both String and Integer of type Object?

tsotsi
  • 683
  • 2
  • 8
  • 20
  • See http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p – Alexis C. Jul 23 '15 at 12:39

2 Answers2

10

Map<String, String> does not extends Map<String, Object>, just like List<String> does not extend List<Object>. You can set the value type to the ? wildcard:

public void output(Map<String, ?> map, String key) {  // map where the value is of any type
    // we can call toString because value is definitely an Object
    System.out.println(map.get(key).toString());
}
M A
  • 71,713
  • 13
  • 134
  • 174
1

The thing you are looking for is the attempt in Java to introduce polymorphism on Collections and is called Generics. More specific to your use case, Wildcards will fit the bill.

An Unbounded Wildcard (see details in Wildcards link) is used by @manouti in his answer, but you can use something more specific than just that: an Upper Bounded Wildcard.

E.g. Map<String, ? extends Object> where Object usually is the most specific but still common class from which all used classes must be derived. For example, if the values in all of your Maps will have a common parent (or 'super') class YourParentClass, then you can replace Object in my example by that class name.

klaar
  • 601
  • 6
  • 17