Is there a Java Map implementation that enforces final keys?

dictionary, java

Solution

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.

Problem

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?

Original source