使用自定义值集合类型创建Commons Collections MultiValueMap



Apache Commons Collections库的4.0版本增加了对泛型的支持。我在转换我的代码以利用它时遇到了问题:

我想要一个MultiValueMap,它以字符串为键,以字符串的集合为值。但是:

  1. 密钥应保持插入顺序(因此我创建通过装饰LinkedHashMap的多值映射(
  2. 值应为每个键都是唯一的,并保留插入顺序(所以我想要值集合类型为LinkedHashSet(

我能得到的最接近的是:

MultiValueMap<String, String> orderedMap = MultiValueMap.multiValueMap(
    new LinkedHashMap<String, Collection<String>>(), 
    LinkedHashSet.class
);

但这就产生了错误:

类型中的方法multiValueMap(Map<K,? super C>, Class<C>)MultiValueMap不适用于参数(LinkedHashMap<String,Collection<String>>, Class<LinkedHashSet>)

所以现在我陷入了仿制药的地狱。欢迎提出任何建议。

在4.0版本之前,我通过以下操作实现了这一点:

MultiValueMap orderedMap = MultiValueMap.decorate(
    new LinkedHashMap<>(), 
    LinkedHashSet.class
);

简单!我提供了LinkedHashMap以使用MultiValueMap行为进行装饰,并指定要用作值的集合类型(LinkedHashSet(。但当我调用put()get()时,这需要强制转换,因此我希望能够使用4.0提供的新通用版本。

我查阅了Apache Commons Collections邮件列表,其中向我解释了MultiValueMap的接口已知缺乏,但将在4.1版中进行改进(请参阅此处了解JIRA问题和相关讨论(。

因此,在未来,我们可能会有一个更好的解决方案,但与此同时,正如Rohit Jain在回答中提到的那样,我们将不得不压制一些警告。然而,由于类型安全的关键方面是MultiValueMap(而不是自定义集合类型(,因此实现这一点的最简单方法是:

@SuppressWarnings({ "rawtypes", "unchecked" })
MultiValueMap<String, String> orderedMap = 
    MapUtils.multiValueMap(new LinkedHashMap(), LinkedHashSet.class);

注意使用MapUtils工厂方法,而不是我在最初的问题中使用的更直接的MultiValueMap

问题是需要传递Class<LinkedHashSet<String>>作为第二个参数。你不能直接创建。你需要做一些石膏。

这会很好:

@SuppressWarnings("unchecked")
MultiValueMap<String, String> orderedMap = 
           MultiValueMap.multiValueMap(
                new LinkedHashMap<String, Collection<String>>(), 
                (Class<LinkedHashSet<String>>)(Class<?>)LinkedHashSet.class
           );

最新更新