Using a MultiValueMap from Apache Commons Collections

Tiny picture Tiny · Oct 6, 2014 · Viewed 15.5k times · Source

Given below an example of org.apache.commons.collections.map.MultiValueMap (from commons-collections-3.2.1)

Map<String, Object> multiValueMap = MultiValueMap.decorate(new HashMap<String, Object>());
multiValueMap.put("orderId", 1L);

for(Map.Entry<String, Object> entry : multiValueMap.entrySet()) {

    List<Object> value = (List<Object>) entry.getValue();
    System.out.println(entry.getKey()+" : "+value.get(0));
}

This works fine as it appears. It displays a key and the value associated with the key.


If the declaration is changed as follows,

Map<String, Object> multiValueMap = MultiValueMap.decorate(new HashMap<String, Object>(){{
        put("orderId", 1L);
    }});

then it throws an exception -

java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.List

at the first line in the only foreach loop given.

In this case, the given MultiValueMap is not really a MultiValueMap. It is rather a usual HashMap.

How does changing the declaration in this way make a difference?

Answer

mikea picture mikea · Oct 6, 2014

MultiValueMap is a fairly simple map decorator. It overrides the put methods and injects collections rather than the actual value. In the case of gets, it gets the collection from the underlying map.

In your second example you are decorating a populated map so when the MultiValueMap attempts to get the collection for your key, it gets a long instead:

 public Collection  getCollection(Object key) {
    return (Collection) getMap().get(key);
}