views:

119

answers:

4

I'm looking for a common data sctructure that has the capabilities of a Map<K, List<V>>

Currently what I do is something like

public class MapOfLists <K,V>{

     private Map<K, List<V>> map = new HashMap<K, List<V>>();

     public void addItem(K key, V value){
        if(!map.containsKey(key)){
            map.put(key, new ArrayList<V>());
        }
        List<V> list = map.get(key);
        list.add(value);
     }
     ...
}

Isn't there a more generic solution? Am I reinventing the wheel (or a less important artifact)

+6  A: 

Like a Google MultiMap....or Apache Commons DefaultMapBag.

Personally, I see nothing wrong with your approach. You're trading off the time it took to write (not that long) and maintain against having another dependency on a 3rd party library like Google. Your approach is defensible.

duffymo
Since I already use apache commons, isn't there a solution on their side?
Ehrann Mehdan
Yes, I've added a link to the Apache Commons DefaultMapBag.
duffymo
Thanks again for the answer
Ehrann Mehdan
+1  A: 

There is nothing in core Java that would do what you're trying to do.

There may be some in third-party libraries, but I've always written my own class since it's relatively simple.

Milan Ramaiya
+2  A: 

I would go with Google Multimap. I wouldn't use the Apache Commons Collections library because it doesn't support generics, and the Google Collection library is pretty decent, so I have been using instead of the Apache Commons Collections for a while now. The thing about all the classes in the Google Collections class, and even in the Apache Commons Lang, is that if you look at most of its methods they will usually be small, and it will save one or two lines at a time of coding for you.

But in the long run, when you don't have a lot of conditional blocks in your code to check if a object is null before [comparing it][2] or if a list exists in a map to make a choice (to then add an item or create the list and put it in the map), your code will end up being more readable and with less noise around.

[2]: http://commons.apache.org/lang/api-2.4/org/apache/commons/lang/ObjectUtils.html#equals%28java.lang.Object, java.lang.Object)

Ravi Wallau
+2  A: 

I tend to use a map to an immutable singly linked list, usually calling it Cons for historic reasons, where the list is terminated with a null. In that case, the code above reduces to:

public void addItem(K key, V value) {
    map.put ( key, new Cons<V> ( value, map.get ( key ) ) );
}

since creating a cons with null as its tail is valid.

Pete Kirkham
Interesting approach
Ehrann Mehdan