Reputation: 26522
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.
Upvotes: 26
Views: 7732
Reputation: 1627
Use GenericMap custom class and another generic class GenericKey for the key, you can see complete example in this answer
Java map with values limited by key's type parameter
Upvotes: 0
Reputation: 198211
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
.
Upvotes: 27