是否有强制执行最终键的 Java Map 实现?

2022-09-03 07:06:07

我需要一个 ,一旦一个键得到一个值,任何将值放在同一键上的额外尝试都会引发异常。Map

例如:

map.put("John", 3); //OK
map.put("John", 7); // throws some exception
map.put("John", 11); // throws some exception

当然,我可以自己实现它(例如,通过扩展 ,或将每个调用都包围给 ),但我更喜欢使用现成的东西来保持我的代码干净。HashMapputif map.contains(key)

有人知道这样的实施吗?


答案 1

JDK 中没有这样的实现。您最好的选择是使用组合:

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
}

否则,正如其他人建议的那样,如果您使用番石榴,请使用ForwardingMap;这本质上是上述代码的通用版本。

事实上,一定要使用番石榴。


其他注意事项:你不能只是在这里;的 不会声明引发任何异常,因此您唯一的选择就是在此处引发未经检查的异常。// throws some exceptionMap.put()


答案 2

Google Java库(Guava)中的ImmutableMap类是您正在寻找的解决方案。您需要最终键,这意味着地图中的值也将是最终的。你可以像这样构建你的地图:

ImmutableMap<String,Integer> myMap = ImmutableMap.<String, Integer>builder()
    .put("john", 3) 
    .put("rogerio", 5)
    .put("alfonso", 45)
    .put("leonidas", 577)
    .build();

推荐