You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by Ryan Bennetts <mo...@gmail.com> on 2014/03/27 00:59:32 UTC

[collections] MultiValueMap with a custom value collection type

Hello all

I am having trouble understanding how to use a custom value collection type
with a MultiValueMap. I want to use the new generics-supported version, but
can't see how to do this without excessive casting, which seems to defeat a
lot of the purpose of using generics in the first place. I have posted this
issue on stackoverflow <http://stackoverflow.com/questions/22625575> but
thought I would ask here too.

I would like a MultiValueMap<http://commons.apache.org/proper/commons-collections/javadocs/api-release/org/apache/commons/collections4/map/MultiValueMap.html>which
takes a String as a key, and a collection of Strings as the value.
But:

   1. The keys should retain insertion ordering (so I create the
   multi-valued map by decorating a
LinkedHashMap<http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html>
   )
   2. The values should be unique for each key and retain insertion
   ordering (so I want the values Collection type to be a
LinkedHashSet<http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html>
   ).

The closest I can get is:

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

But that produces this error:

The method multiValueMap(Map<K,? super C>, Class<C>) in the type
MultiValueMap 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. One
suggestion I have received is to use:

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

This works but do I really have to do two casts? Is this really what the
api designers intended?

Prior to version 4.0, I accomplished that with the following:

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

Which is certainly simpler, but not type safe. 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.

Thanks,

-- Ryan

Re: [collections] MultiValueMap with a custom value collection type

Posted by Ryan Bennetts <mo...@gmail.com>.
Hi Thomas

Thanks very much for your reply. I'll look forward to version 4.1, but in
the meantime I'll go with your suggested code.

Thanks again,

-- Ryan

 > Hello all
> >
> > I am having trouble understanding how to use a custom value collection
> type
> > with a MultiValueMap...
>


> Hi Ryan,
>
> we know that the MultiValueMap is flawed for several reasons, but we are
> working on adding a revamped variant in 4.1, see the issue:
>
> https://issues.apache.org/jira/browse/COLLECTIONS-508
>
> The best thing you can do right now is to instantiate it in the
> pre-generics way:
>
> @SuppressWarnings({ "rawtypes", "unchecked" })
> MultiValueMap<String, String> orderedMap
>   = MapUtils.multiValueMap(new LinkedHashMap(), LinkedHashSet.class);
>
> You actually need type-safety for orderedMap, not for the argument to
> multiValueMap. The need to suppress warnings is annoying, but with 4.1
> this should also go away.
>
> Thomas
>

Re: [collections] MultiValueMap with a custom value collection type

Posted by Thomas Neidhart <th...@gmail.com>.
On 03/27/2014 12:59 AM, Ryan Bennetts wrote:
> Hello all
> 
> I am having trouble understanding how to use a custom value collection type
> with a MultiValueMap. I want to use the new generics-supported version, but
> can't see how to do this without excessive casting, which seems to defeat a
> lot of the purpose of using generics in the first place. I have posted this
> issue on stackoverflow <http://stackoverflow.com/questions/22625575> but
> thought I would ask here too.
> 
> I would like a MultiValueMap<http://commons.apache.org/proper/commons-collections/javadocs/api-release/org/apache/commons/collections4/map/MultiValueMap.html>which
> takes a String as a key, and a collection of Strings as the value.
> But:
> 
>    1. The keys should retain insertion ordering (so I create the
>    multi-valued map by decorating a
> LinkedHashMap<http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html>
>    )
>    2. The values should be unique for each key and retain insertion
>    ordering (so I want the values Collection type to be a
> LinkedHashSet<http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html>
>    ).
> 
> The closest I can get is:
> 
> MultiValueMap<String, String> orderedMap = MultiValueMap.multiValueMap(
>     new LinkedHashMap<String, Collection<String>>(),
>     LinkedHashSet.class);
> 
> But that produces this error:
> 
> The method multiValueMap(Map<K,? super C>, Class<C>) in the type
> MultiValueMap 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. One
> suggestion I have received is to use:
> 
> @SuppressWarnings("unchecked")MultiValueMap<String, String> orderedMap
> = MultiValueMap.multiValueMap(
>     new LinkedHashMap<String, Collection<String>>(),
>     (Class<LinkedHashSet<String>>)(Class<?>)LinkedHashSet.class);
> 
> This works but do I really have to do two casts? Is this really what the
> api designers intended?
> 
> Prior to version 4.0, I accomplished that with the following:
> 
> MultiValueMap orderedMap = MultiValueMap.decorate(
>     new LinkedHashMap<>(),
>     LinkedHashSet.class);
> 
> Which is certainly simpler, but not type safe. 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.

Hi Ryan,

we know that the MultiValueMap is flawed for several reasons, but we are
working on adding a revamped variant in 4.1, see the issue:

https://issues.apache.org/jira/browse/COLLECTIONS-508

The best thing you can do right now is to instantiate it in the
pre-generics way:

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

You actually need type-safety for orderedMap, not for the argument to
multiValueMap. The need to suppress warnings is annoying, but with 4.1
this should also go away.

Thomas

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org