3

Javaの既存のオープン ソースMap実装はありますか?これは通常のキーと値のマップですが、キーごとに複数の値サポートしますか? 私が見つけたマルチマップの実装は、キーをコレクションに関連付けているように見えますが、既存のコードのドロップイン置換が必要なため、これではうまくいきません。

「それはできない」と言っている人もいると思うので、広く使用されているフレームワークである Qt で動作する方法の例を次に示します。QMapclassのドキュメントからの抜粋を次に示します。

マップにキーkeyを持つアイテムが含まれていない場合、関数はデフォルトで構築された値を返します。マップにキーの項目が複数ある場合は、最後に挿入された項目の値が返されます。

私の必要性は非常に限られているので、現時点では以下のハックを使用しています。削除はなく、キーごとに多くの値が例外であり、重複したキーが少し壊れても問題ないため、これで十分です。

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;
}

しかし、もしあれば、より良い解決策が欲しいです...

4

2 に答える 2

0

Guava ライブラリには、Multimapキーごとに複数の値を許可する があります:)

于 2012-11-15T11:09:49.500 に答える
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);

}

大ざっぱにテストされているだけですが

于 2012-11-15T14:03:24.790 に答える