0

I currently have a method like this:

public static Report createReport(Map<String,Object> parameters) {...}

I'm trying to figure out if there is a way I can change the generic specification so that it will accept both Map<String,Object>s and Map<String,String>s for parameters.

Note that createReport needs to be able to add entries to parameters. Is this possible?

Brad Mace
  • 26,280
  • 15
  • 94
  • 141

3 Answers3

2

Please see:

Difference between <? super T> and <? extends T> in Java

Specifically this answer. The PECS (producer extends, consumer supers) rule is ingenious. Try:

public static Report createReport(Map<String,? super String> parameters) {...}

You'll be able to add Strings and read Objects:

parameters.put("a,", "b");
Object object = parameters.get("c");
Community
  • 1
  • 1
lexicore
  • 39,549
  • 12
  • 108
  • 193
  • This looks like the closest I could get, but doesn't let me add other types of Objects. It appears generics aren't the answer in this situation. – Brad Mace Nov 25 '14 at 18:04
0

If you were only reading the values out of the Map you could have done something like this:

public static Report createReport(Map<String,?> parameters) {...}

However, since you also want to add enteries, you need to know the type, or at least be able to know that the type in the Map is the same as the type you are adding.

If it is variable, then I would suggest having another parameter that does the conversion to the type you need.

interface Converter<T>{

    T convert(Object o);
}

Then add that parameter to your createReport method like this:

public static <T> Report createReport(Map<String,T> parameters, Converter<T> converter) {...}

Then inside your method you can do something like this:

   T value = converter.convert(foo);

   parameters.put(key, value);

It would then be up to the caller of createReport to provide the correct converter.

dkatzel
  • 29,286
  • 2
  • 57
  • 64
0

No it is not possible. There is no type-union in Java. You have to revert to the lowest common superclass, which is in your case Object. In some cases you could use an Interface instead, like for example a collection type or a -able style (Closeable) interface.

eckes
  • 9,350
  • 1
  • 52
  • 65