4

下面给出了一个示例org.apache.commons.collections.map.MultiValueMap(来自 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));
}

这看起来很好。它显示一个键和与该键关联的值。


如果声明更改如下,

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

然后它抛出一个异常 -

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

foreach给定的唯一循环的第一行。

在这种情况下,给定MultiValueMap的并不是真正的MultiValueMap. 这是相当平常的HashMap

以这种方式更改声明有何不同?

4

3 回答 3

3

MultiValueMap 是一个相当简单的地图装饰器。它覆盖 put 方法并注入集合而不是实际值。在获取的情况下,它从底层地图中获取集合。

在您的第二个示例中,您正在装饰一个填充的地图,因此当 MultiValueMap 尝试获取您的键的集合时,它会变得很长:

 public Collection  getCollection(Object key) {
    return (Collection) getMap().get(key);
}
于 2014-10-06T12:53:20.717 回答
1
Map<String, Object> multiValueMap = MultiValueMap.decorate(new HashMap<String, Object>());
multiValueMap.put("orderId", 1L);

在上面的版本中,put(...) 是在变量 multiValueMap 上调用的。

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

在这个版本中,put(...) 是在类的实例初始化器中调用的,在加倍 {{ 之前,即在 HashMap 上。

因此,两段代码是不等价的。

于 2014-10-06T13:04:19.137 回答
1
Map<String, Object> multiValueMap1 = new HashMap<String, Object>() {
        {
            put("orderId",
                    new ArrayList<Object>(Arrays
                            .asList(new Object[] { 1L })));
        }
    };
于 2014-10-06T12:35:35.640 回答