I have a Map
whose keys are of generic type Key<T>
, and values are of type List<T>
. If the key is an instance of Key<String>
, the value must be a List<String>
, and the same rule applies to any other key-value pairs. I have tried the following but it does not compile:
Map<T, List<T>> map;
At present I have to declare it with "partial" generics:
Map<Object, List> map;
I know this is bad but I currently have no better choice. Is it possible to use generics in this situation?
UPDATE
Maybe I didn't express my problem clearly. I want a map that is able to:
map.put(new Key<String>(), new ArrayList<String>());
map.put(new Key<Integer>(), new ArrayList<Integer>());
And the following code should not compile:
map.put(new Key<String>(), new ArrayList<Integer>());
The key and value should always have the same generic type while the generic type can be any, and obviously extending a map does not meet my requirement.
I'm not aware of any existing library that does precisely this but it is not too hard to implement yourself. I've done something similar a few times in the past. You cannot use the standard Map interface but you can use a hash map inside to implement your class. To start, it might look something like this:
public class KeyMap {
public static class Key<T> { }
private final HashMap<Object,List<?>> values = new HashMap<Object,List<?>>();
public <T> void put(Key<T> k, List<T> v) {
values.put(k, v);
}
public <T> List<T> get(Key<T> k) {
return (List<T>)values.get(k);
}
public static void main(String[] args) {
KeyMap a = new KeyMap();
a.put(new Key<String>(), new ArrayList<String>());
a.get(new Key<Integer>());
}
}
This is what you want:
public class Test<T> extends HashMap<T, List<T>>
{
}
If you don't want a HashMap as the super class then change it to whatever concrete class you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With