I need a Map
, that once a key gets a value, any additional attempt of putting a value on the same key will throw an exception.
For example:
map.put("John", 3); //OK
map.put("John", 7); // throws some exception
map.put("John", 11); // throws some exception
Of course I can implement this on my own (e.g. by extending HashMap
, or surrounding every call to put
with if map.contains(key)
), but I prefer using something ready-made that keeps my code clean.
Does anybody know of such implementation?
There is no such implementation in the JDK. Your best bet here is to use composition:
public final class CustomMap<K, V>
implements Map<K, V>
{
private final Map<K, V> delegate;
public CustomMap(final Map<K, V> delegate)
{
this.delegate = delegate;
}
@Override
public V put(final K key, final V value)
{
// Can't use the return value of delegate.put(), since some implementations
// allow null values; so checking delegate.put() == null doesn't work
if (delegate.containsKey(key))
throw new IllegalArgumentException("duplicate key: " + key);
return delegate.put(key, value);
}
@Override
public void putAll(@Nonnull final Map<? extends K, ? extends V> m)
{
for (final Entry<? extends K, ? extends V> entry: m.entrySet())
put(entry.getKey(), entry.getValue());
}
// delegate all other methods
}
Otherwise, as others suggested, if you use Guava, use ForwardingMap; this is essentially a generalized version of the above code.
In fact, do use Guava.
other note: you can't just // throws some exception
here; Map
's .put()
doesn't declare to throw any exception, so your only option is to throw an unchecked exception here.
ImmutableMap
class in Google Java libraries (Guava) is the solution you are looking for. You want final keys which implies that the values in your map will also be final-alike.
And you can build your map like this:
ImmutableMap<String,Integer> myMap = ImmutableMap.<String, Integer>builder()
.put("john", 3)
.put("rogerio", 5)
.put("alfonso", 45)
.put("leonidas", 577)
.build();
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