3

I am just learning how to use wildcards and bounded type parameters. I want to use (I think) bounded wildcards in a method that is passed a HashMap. I've seen examples of bounded type parameters and bounded wildcards but I haven't found anything that shows me how to pass a HashMap into a method where the HashMap can contain different value objects.

Map<Integer, Company>
Map<Integer, Employee>
Map<Integer, Location>

This is what I have as an example for the first Map listed above:

public Map<Integer, Company> readXML(Map<Integer, Company> companies) {

I want to use something like the following to enable this method to deal with any one of my Maps listed above.

public Map<Integer, ?> readXML(Map<Integer, ?> values) {

Can somebody show me an example for how I can use wildcards for the Map values in this method?

1) Do I need to create a Map class that extends the value objects (Company, Employee, Location)?

2) Or is there a better way to accomplish this? In other words, am I doing it wrong?

Thank you for your advice.

Patricia
  • 5,019
  • 14
  • 72
  • 152
  • What is the relationship between `Company`, `Employee` and `Location`? Do they have a common supertype other than `Object`? – Andy Turner Oct 04 '15 at 16:47
  • To constrain (represent a relationship) between parameter types or between parameter and return type, you have to use a type variable. Wildcards don't allow you to create such relationship, they just constrain the particular parameter or return type. – RealSkeptic Oct 04 '15 at 16:49
  • @AndyTurner - the only common supertype is Object. I am simply trying to come up with a clever (non-newbie) way to use the same XML parser method to parse the values for any of my Map Object's values. – Patricia Oct 04 '15 at 17:11

1 Answers1

2

Since your method readXML(Map<Integer, ?(V)> companies) can accept V of type Company, Employee and Location. You can solve this in below mentioned ways.

  1. You can make all the mentioned classes to extend new class or can be made to implement our custom Type interface and use that type for V or

  2. Add additional parameter to your method which sends Class information to it, while calling the api.

    public <V> Map<Integer, V> readXML(Map<Integer, V> values, Class<V> clazz) {
        if(clazz == Integer.class) {
            ...
        } else if// or if all the class type has same implementation use the 
                 // || operator in the above if condition only. 
                ...
        //and finally
        else {
            // either throw **IllegalArgument/Unsupported operation** exception
            // for the type 'V' Or handle in any other way you like to implement
        }
    }
    

    Lastly, IllegalArgument / UnsupportedOperation exception is unchecked exception. Make sure you properly document your method, if you decide to throw the exception.

Community
  • 1
  • 1
rajuGT
  • 6,224
  • 2
  • 26
  • 44
  • 1
    `Class clazz` will generate a raw type warning when compiled. The correct signature should be `public Map readXML(Map values, Class clazz)`. – VGR Oct 06 '15 at 01:25