Generics for a multiplevalue hashmap

Discussion in 'Java' started by Alexis Berry, Jul 18, 2011.

  1. Alexis Berry

    Alexis Berry Guest

    Hello,

    I want to create a HashMap which has a list for each key. Therefore I can store more than one value for each key. (I know this breaks the true use of a hashmap but I want a datastruture that takes one key and hold multiple value)

    I thought I would be able to define:

    public class MultipleValueHashMap<T, java.util.List<U>> implements Map<T, java.util.List<U>> {

    .....
    }

    I would then construct it by "new MultipleValueHashMap<Inteteger, List<String>()"

    Unfortunately this does not compile. I think it might be because I am mixing generic types with real types. Am I correct?

    Is there a way I can use a map to store more than one value and use generics?

    Thanks
    Alexis Berry, Jul 18, 2011
    #1
    1. Advertising

  2. Alexis Berry

    markspace Guest

    On 7/18/2011 2:31 PM, Alexis Berry wrote:

    > Unfortunately this does not compile. I think it might be because I am
    > mixing generic types with real types. Am I correct?



    Sort of. You can't put constraints on the parameter type the way you
    are thinking.


    > public class MultipleValueHashMap<T, java.util.List<U>> implements
    > Map<T, java.util.List<U>> {



    Should be:

    public class MultipleValueHashMap<T, U> implements
    Map<T, java.util.List<U>> {

    I think. I'll check it in a sec and post again if it needs correcting.
    markspace, Jul 18, 2011
    #2
    1. Advertising

  3. On 11-07-18 06:31 PM, Alexis Berry wrote:
    > Hello,
    >
    > I want to create a HashMap which has a list for each key. Therefore I can store more than one value for each key. (I know this breaks the true use of a hashmap but I want a datastruture that takes one key and hold multiple value)
    >

    Why does it break the "true use" of a hashmap? The use of a map or
    dictionary or associative array - whatever you choose to call it - is to
    relate a collection of keys and values such that each key is associated
    with a value. That value may be anything, including a list or set of values.

    As it happens a map which has lists or sets as values is a typical
    implementation of a so-called multimap. Good multimap interfaces make
    the implementation easier to use but don't hide it much. See the
    Wikipedia entry on multimap for some references to implementations.

    I won't address the rest of the post because others will already be all
    over it. :)

    AHS
    Arved Sandstrom, Jul 19, 2011
    #3
  4. Alexis Berry

    Arne Vajhøj Guest

    On 7/18/2011 5:31 PM, Alexis Berry wrote:
    > I want to create a HashMap which has a list for each key. Therefore I can store more than one value for each key. (I know this breaks the true use of a hashmap but I want a datastruture that takes one key and hold multiple value)
    >
    > I thought I would be able to define:
    >
    > public class MultipleValueHashMap<T, java.util.List<U>> implements Map<T, java.util.List<U>> {
    >
    > ....
    > }
    >
    > I would then construct it by "new MultipleValueHashMap<Inteteger, List<String>()"
    >
    > Unfortunately this does not compile. I think it might be because I am mixing generic types with real types. Am I correct?
    >
    > Is there a way I can use a map to store more than one value and use generics?


    public class MM1<T,U> implements Map<T, List<U>> {
    ....
    MM1<Integer,String> mm = new MM1<Integer,String>();

    or

    public class MM2<T,U> extends HashMap<T, List<U>> {
    ....
    MM2<Integer,String> mm = new MM2<Integer,String>();

    seems obvious to me.

    Arne
    Arne Vajhøj, Jul 19, 2011
    #4
  5. Alexis Berry

    Roedy Green Guest

    On Mon, 18 Jul 2011 14:31:33 -0700 (PDT), Alexis Berry
    <> wrote, quoted or indirectly quoted someone
    who said :

    >I want to create a HashMap which has a list for each key. Therefore I can store more than one value for each key.
    >I know this breaks the true use of a hashmap but I want a datastruture that takes one key and hold multiple value)


    I invented such a beast for String multivalues. Source:
    https://wush.net/websvn/mindprod/fi...indprod/replicatorcommon/MultiProperties.java
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com
    One thing I love about having a website, is that when I complain about
    something, I only have to do it once. It saves me endless hours of grumbling.
    Roedy Green, Jul 19, 2011
    #5
  6. Alexis Berry

    Esmond Pitt Guest

    On 19/07/2011 7:31 AM, Alexis Berry wrote:
    > public class MultipleValueHashMap<T, java.util.List<U>> implements Map<T, java.util.List<U>> {


    public class MultipleValueHashMap<T, <L extends java.util.List<U>>>
    implements Map<T, L> ?
    Esmond Pitt, Jul 19, 2011
    #6
  7. Alexis Berry

    Stefan Ram Guest

    Alexis Berry <> writes:
    >public class MultipleValueHashMap<T, java.util.List<U>> implements Map<T, java.util.List<U>> {


    I'd just use:

    Multimap<D,V>

    . When you just implement Map, not HashMap, then why use
    »Hash« in the name of the class?

    Also, you do not want to implement the map interface, but
    your custom interface, so why do you want to announce that
    you implement Map via an « implements » clause at all?

    D is the domain.

    V is the type of the values.

    add(d,v) adds the value v to the set of d

    You need to decided whether you want a set or a bag.
    When you use a bag, then »add(d,v);add(d,v);« will
    increment the multiplicity of v by 2. If you use a
    set, »add(d,v);add(d,v);« is the same as »add(d,v);«.

    You could be more flexible with a delegate for the
    collection:

    class Multimap<D,V>
    { public Multimap( Container c, ... ){ ... } ... }

    In this case

    add(d,v)

    will add v to the container of d (it will create a new
    container, if such a container does not exist yet), using
    the add method of this container, whatever this add method
    does.
    Stefan Ram, Jul 19, 2011
    #7
  8. Alexis Berry

    markspace Guest

    On 7/19/2011 5:24 AM, Esmond Pitt wrote:
    > On 19/07/2011 7:31 AM, Alexis Berry wrote:
    >> public class MultipleValueHashMap<T, java.util.List<U>> implements
    >> Map<T, java.util.List<U>> {

    >
    > public class MultipleValueHashMap<T, <L extends java.util.List<U>>>
    > implements Map<T, L> ?



    Well, this doesn't work for a couple of reasons. First, in terms of
    syntax, you still have to declare U as a type parameter:

    public class GenericTest<T, U, L extends List<U>>
    extends AbstractMap<T, List<U>> {

    Secondly, "List" here is both an input and and output. And going by
    PECS -- Producer Extends, Consumer Super -- you can't use just one. So
    I think the default is just to try to get the right type there (List
    works) and be careful with your type declarations.
    markspace, Jul 19, 2011
    #8
  9. Alexis Berry

    Stefan Ram Guest

    -berlin.de (Stefan Ram) writes:
    >Alexis Berry <> writes:
    >>public class MultipleValueHashMap<T, java.util.List<U>> implements Map<T, java.util.List<U>> {

    >I'd just use:
    >Multimap<D,V>


    For example:

    public class Main
    {
    public static void main( final java.lang.String[] args )
    {
    final Multimap<java.lang.Integer,java.lang.Integer> m
    = new DefaultSetMap<java.lang.Integer,java.lang.Integer>();
    m.add( 1, 1 ); m.add( 2, 2 ); m.add( 2, 3 );
    java.lang.System.out.println( m ); }}

    This prints:

    {1=[1], 2=[2, 3]}

    Rest of the source code (I suggest to quote only parts one
    directly refers to):

    interface Container<V>
    { public void add( final V v );
    public java.lang.String toString(); }

    interface ContainerFactory<V>
    { public Container<V> newContainer(); }

    class DefaultContainer<V> implements Container<V>
    { final java.util.Set<V> set;
    public DefaultContainer()
    { this.set = new java.util.HashSet<V>(); }
    public void add( final V v )
    { this.set.add( v ); }
    public java.lang.String toString()
    { return this.set.toString(); }}

    class DefaultContainerFactory<V> implements ContainerFactory<V>
    { public DefaultContainer<V> newContainer()
    { return new DefaultContainer<V>(); }}

    interface Multimap<D,V>
    { public void add( final D d, final V v );
    public java.lang.String toString(); }

    class DefaultMultimap<D,V> implements Multimap<D,V>
    { final java.util.Map<D,Container<V>> map;
    final ContainerFactory<V> containerFactory;
    public DefaultMultimap
    ( final java.util.Map<D,Container<V>> map,
    final ContainerFactory<V> containerFactory )
    { this.map = map;
    this.containerFactory = containerFactory; }
    public boolean exists( final D d ){ return this.map.containsKey( d ); }
    public Container<V> get( final D d ){ return this.map.get( d ); }
    public void set( final D d, final Container<V> v )
    { this.map.put( d, v ); }
    public void add( final D d, final V v )
    { if( !this.exists( d ))this.set( d, this.containerFactory.newContainer() );
    this.get( d ).add( v ); }
    public java.lang.String toString()
    { return this.map.toString(); }}

    class DefaultSetMap<D,V> implements Multimap<D,V>
    { final Multimap<D,V> multimap;
    public DefaultSetMap()
    { this.multimap = new DefaultMultimap<D,V>
    ( new java.util.HashMap<D,Container<V>>(),
    new DefaultContainerFactory<V>() ); }
    public void add( final D d, final V v )
    { this.multimap.add( d, v ); }
    public java.lang.String toString()
    { return this.multimap.toString(); }}

    One can observe that DefaultMultimap<D,V> is defined without any
    fixed container for the multiple values of a key. Such a container
    is only added in DefaultSetMap<D,V>.
    Stefan Ram, Jul 19, 2011
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Vince Darley
    Replies:
    4
    Views:
    4,417
    emilchacko
    Mar 2, 2010
  2. David Harrigan

    Generics and use of extends in HashMap

    David Harrigan, Oct 2, 2006, in forum: Java
    Replies:
    5
    Views:
    724
    Thomas Hawtin
    Oct 2, 2006
  3. Rakesh
    Replies:
    10
    Views:
    12,170
    Mike Schilling
    Apr 8, 2008
  4. rockdale
    Replies:
    6
    Views:
    1,658
  5. Richard
    Replies:
    2
    Views:
    387
    lewbloch
    Jul 21, 2011
Loading...

Share This Page