The 4.0 release of the Apache Commons Collections library has added generics support. I am having trouble converting my code to take advantage of it:
I would like a MultiValueMap
which takes a String as a key, and a collection of Strings as the value. But:
LinkedHashMap
)LinkedHashSet
).The closest I can get is:
MultiValueMap<String, String> orderedMap = MultiValueMap.multiValueMap(
new LinkedHashMap<String, Collection<String>>(),
LinkedHashSet.class
);
But that produces the error:
The method
multiValueMap(Map<K,? super C>, Class<C>)
in the typeMultiValueMap
is not applicable for the arguments(LinkedHashMap<String,Collection<String>>, Class<LinkedHashSet>)
So now I am in generics hell. Any suggestions would be most welcome.
Prior to version 4.0, I accomplished that with the following:
MultiValueMap orderedMap = MultiValueMap.decorate(
new LinkedHashMap<>(),
LinkedHashSet.class
);
Simple! I provide the LinkedHashMap
to decorate with MultiValueMap
behaviour, and specify the type of collection (LinkedHashSet
) to use as the values. But that requires casting when I call put()
and get()
and so I'd like to be able to use the new generic version provided by 4.0.
I consulted the Apache Commons Collections mailing list, where it was explained to me that the interface for MultiValueMap
is known to be lacking, but will be revamped in version 4.1 (see here for the JIRA issue and associated discussion).
So in the future we may have a better solution, but in the meantime, as Rohit Jain mentioned in his answer, we're just going to have to suppress some warnings. However, since the key aspect of type safety is for the MultiValueMap
(not the custom collection type), the simplest way to achieve this is:
@SuppressWarnings({ "rawtypes", "unchecked" })
MultiValueMap<String, String> orderedMap =
MapUtils.multiValueMap(new LinkedHashMap(), LinkedHashSet.class);
Note the use of the MapUtils
factory method, rather than the more direct MultiValueMap
which I had used in my original question.