Java的Qt类多值映射?

时间:2012-11-15 10:56:08

标签: java collections map multimap

是否存在针对java的现有开源Map实现,这将是一个普通的键值映射,但是否支持每个键的多个值?我发现的多图实现似乎将密钥与集合相关联,这并没有完全削减它,因为我需要替代现有代码。

我感觉有些人说“你不能这样做”,所以这里有一个例子,说明它在一个广泛使用的框架中的表现方式,Qt。以下是QMap class的文档的摘录:

  

如果地图中没有包含键的项目,则该函数返回a   默认构造的值。如果键中有多个项目   map,返回最近插入的值。

我的需求非常有限,所以目前我正在使用下面的黑客,这是足够的,因为没有删除和每个键的许多值是异常,并且重复键有点受到损害不是问题:

public static <V, V2 extends V> String mapMultiPut(
        Map<String, V> map, 
        String key, 
        V2 value) {
    int count = 0;
    String tmpKey = key;
    while (map.containsKey(tmpKey)) {
        ++count;
        tmpKey = key + '_' + count;
    }
    map.put(tmpKey, value);
    return tmpKey;
}

但我想要一个更好的解决方案,如果存在......

2 个答案:

答案 0 :(得分:0)

Guava库有Multimap,每个键允许多个值:)

答案 1 :(得分:0)

您可以使用ListMultimap和

Iterables.getLast(listMultiMap.get(key), defaultValue(key))

您可以在其中定义自己的defaultValue方法。

这假设您实际上并不需要班级中的Map界面。

如果真的想要Map你可以试试这个

public abstract class QtMap<K, V> extends ForwardingMap<K, V>
{
    private final ListMultimap<K, V> listMultimap = ArrayListMultimap.create();

    final Map<K, V> delegate = Maps.<K, Collection<V>, V> transformEntries(listMultimap.asMap(), new EntryTransformer<K, Collection<V>, V>()
    {

        @Override
        public V transformEntry(K key, Collection<V> value)
        {
            return Iterables.getLast(value, defaultValue(key));
        }

    });

    @Override
    protected Map<K, V> delegate()
    {
        return delegate;
    }

    @Override
    public V put(K key, V value)
    {
        listMultimap.put(key, value);
        return null;
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> map)
    {
        for (Map.Entry<? extends K, ? extends V> entry : map.entrySet())
        {
            put(entry.getKey(), entry.getValue());
        }
    }

    @Override
    public V get(Object key)
    {
        return listMultimap.containsKey(key) ? delegate.get(key) : defaultValue(key);
    }

    protected abstract V defaultValue(Object key);

}

虽然它只是经过粗略测试