Java generics enforce same type for keys and values of map
dictionary, generics, java
Solution
You can do this, but you have to roll your own wrapper on top of a `Map`:
class MyTypeSafeMap {
private Map<Key<?>, Value<?>> map;
public <T> void put(Key<T> key, Value<T> value) {
map.put(key, value);
}
public <T> Value<T> get(Key<T> key) {
return (Value) map.get(key);
// we know it's safe, but the compiler can't prove it
}
}
Compare e.g. Guava's `ClassToInstanceMap`.
Problem
What I am looking for: I'm looking to construct something that enforces type on both the keys and values of a map: kind of like `Map<Key<X>, Value<X>>`. However, I would additionally like to enforce that types match within each key/value entry, but between entries, no type must should be enforced. For example, within the same map, these key/value pairs should be considered valid: - `Key<Integer>` maps to `Value<Integer>` - `Key<String>` maps to `Value<String>` - `Key<Double>` maps to `Value<Double>` However, something like this would be invalid: - `Key<Integer>` mapping to `Value<String>` - `Key<Double>` mapping to `Value<Boolean>` How can I accomplish this using Java generics? What I'm not looking for: I understand that I can implement something like `Set<Pair>`, where pair accepts Key/Value of the same type. However, looking this up by key would no longer be a constant time operation. I understand that I could do something like `Map<Key<?>, Value<?>>` and just assert that the Key and Value are the same type at runtime. However, I was wondering if this is possible strictly using generics.