是否存在强制最终密钥的Java Map实现?

时间:2014-06-02 08:43:44

标签: java map

我需要一个Map,一旦一个键获得一个值,任何在同一个键上放置一个值的额外尝试都会抛出异常。

例如:

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

当然我可以自己实现这一点(例如通过扩展HashMap,或者使用put将每次调用都包含在if map.contains(key)中),但我更喜欢使用现成的内容我的代码干净。

有人知道这样的实施吗?

2 个答案:

答案 0 :(得分:13)

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
}

否则,正如其他人所说,如果您使用Guava,请使用ForwardingMap;这基本上是上述代码的通用版本。

事实上,使用番石榴。


其他说明:你不能只在这里// throws some exception; Map的{​​{1}}未声明抛出任何异常,因此您唯一的选择是在此处抛出未经检查的异常。

答案 1 :(得分: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();