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.
The term generic simply is the idea of allowing the type (Integer, Double, String, etc. or any user-defined type) to be the parameter to methods, class, or interface. For eg, all the inbuilt collections in java like ArrayList, HashSet, HashMap, etc. use generics.
Multiple parametersYou can also use more than one type parameter in generics in Java, you just need to pass specify another type parameter in the angle brackets separated by comma.
You cannot have same key added in a Map with different values. Keys are always unique, the time you add another key with same value, the older gets overridden.
HashMap is a collection to store (key,value) pairs and According to the documentation of HashMap the keys are always unique. If you add a key which already exists(collision) in the hashmap, the old value will be replaced.
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
.
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