簡體   English   中英

收藏地圖

[英]Map of collections

我想用Java制作集合地圖,所以我可以制作類似的東西

public void add(K key, V value) {  
    if (containsKey(key)) {
        get(key).add(value);
    } else {
        Collection c = new Collection();
        c.add(value);
        put(key, value);
    }
}

我試圖用類似的東西制作它

public class CollectionMap<K, C extends Collection<V>> extends HashMap<K, C>

但編譯器抱怨<V>部分,並且仍然存在制作正確的新集合的問題。

目前,我已經創建了兩個類:SetMap,看起來像這樣

 1: public class SetMap<K, V> extends HashMap<K, Set<V>> {
 2: 
 3:    public void add(K key, V value) {
 4:        if (containsKey(key)) {
 5:            get(key).add(value);
 6:        } else {
 7:            Set<V> list = new HashSet<V>();
 8:            list.add(value);
 9:            put(key, list);
10:        }
11:    }
12:
13: }

和ListMap看起來幾乎相同,除了我創建新ArrayList的第7行。 這種重復小到可以容忍,但問題仍然存在於Java中這種“嵌套泛型”可能嗎?

編輯:

正如埃里克森所說 ,解決方案是在<A, B extends Something<A>>而不僅僅是<B extends Something<A>>

所以代碼看起來像

public abstract class CollelctionMap<K, V, C extends Collection<V>> extends HashMap<K, C> {

    protected abstract C newCollection();

    public void add(K key, V value) {
        if (containsKey(key)) {
            get(key).add(value);
        } else {
            C c = newCollection();
            c.add(value);
            put(key, c);
        }
    }
}

而ListMap和SetMap只提供適當的集合

如果mapMap<K, Collection<V>> ,請使用idiom computeIfAbsent(...).add(...)如下所示:

map.computeIfAbsent(key, k -> new ArrayList<>()).add(value);

或者,對於一個Set

map.computeIfAbsent(key, k -> new HashSet<>()).add(value);

如果是一個選項,您可能只想使用Google Collections API - http://code.google.com/p/google-collections/

即使你不能使用它,也許看看他們如何實現他們的MultiMaps將幫助你實現。

您的代碼存在問題:

集合c = new Collection();

無法實例化。

我認為下一段代碼將解決您的問題:

public class CollectionMap<K, V> extends HashMap<K, Collection<V>> {


    ...
    ...
    ...


    public void add(K key, V value) {
        if (containsKey(key)) {
            get(key).add(value);
        } else {
            Collection<V> c = new ArrayList<V>();
            c.add(value);
            super.put(key, c);
        }
    }
}

Apache Commons Collections也提供了一個MultiMap,但它的JDK為1-.5,所以你沒有那里的泛型安全性。 您可以將它包裝在Collections.checkedMap(Key.class,Value.class,collection)中以確保運行時安全。 如果你可以使用谷歌的Colelction API,它提供了一個更加流暢的MultiMap,包括所有的泛型,鈴聲和口哨聲。

如果可能,請使用Google的Guava 伙計們在那里做得很棒。

這是另一種解決方案。

abstract class MultiMap<K, V> {

    private Map<K, Collection<V>> entries = new LinkedHashMap<K, Collection<V>>();

    public void put(K key, V value) {
        Collection<V> values = entries.get(key);
        if (values == null) {
            entries.put(key, values = newValueCollection());
        }
        values.add(value);
    }

    // other methods
    // ..

    abstract Collection<V> newValueCollection();



    // Helper methods to create different flavors of MultiMaps

    public static <K, V> MultiMap<K, V> newArrayListMultiMap() {
        return new MultiMap<K, V>() {
            Collection<V> newValueCollection() {
                return new ArrayList<V>();
            }
        };
    }

    public static <K, V> MultiMap<K, V> newHashSetMultiMap() {
        return new MultiMap<K, V>() {
            Collection<V> newValueCollection() {
                return new HashSet<V>();
            }
        };
        }

 }

你可以像使用它一樣

MultiMap<String, Integer> data = MultiMap.newArrayListMultiMap();
data.put("first", 1);
data.put("first", 2);
data.put("first", 3);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM