81

How I can get the third value for the first key in this map? Is this possible?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Sunscreen
  • 3,452
  • 8
  • 34
  • 40
  • I can get the first value for a key by using the member function of HashMap::get though the third one? I cannot find any code unfortunately. – Sunscreen Nov 22 '11 at 15:43
  • 2
    You cannot find your own code? That's what he is talking about. – Bhesh Gurung Nov 22 '11 at 15:45
  • 1
    Sounds like you might be a little confused about the difference between keys and hashed keys. Hopefully this will set you straight: http://en.wikipedia.org/wiki/Hashmap – vaughandroid Nov 22 '11 at 15:45
  • 4
    A Map can't have multiple values for one key, but you can have a Collection as value instead – Nathan Q Nov 22 '11 at 15:46

15 Answers15

104

Libraries exist to do this, but the simplest plain Java way is to create a Map of List like this:

Map<Object,ArrayList<Object>> multiMap = new HashMap<>();
Yassin Hajaj
  • 21,337
  • 9
  • 51
  • 89
solendil
  • 8,432
  • 4
  • 28
  • 29
  • 4
    However, it may well be simpler to use a library than to roll your own, test it etc... – Jon Skeet Nov 22 '11 at 15:47
  • this solution would only work if the objects in the ArrayList are from the same type. S, f.e. it's not possible to have a key with a int and a double value.. – lydiaP Sep 04 '18 at 21:19
  • @JonSkeet which is the recommended library for this use case? – Gaurav Mar 08 '19 at 18:47
  • 1
    @gaurav: It's been so long since I've been in the Java world that I wouldn't like to say. I'd look at Guava though. – Jon Skeet Mar 08 '19 at 19:13
35

It sounds like you're looking for a multimap. Guava has various Multimap implementations, usually created via the Multimaps class.

I would suggest that using that implementation is likely to be simpler than rolling your own, working out what the API should look like, carefully checking for an existing list when adding a value etc. If your situation has a particular aversion to third party libraries it may be worth doing that, but otherwise Guava is a fabulous library which will probably help you with other code too :)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Apache Commons Collections has also a [Multimap](https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/MultiMap.html) implementation. – Robert Feb 20 '13 at 08:45
26

For example:

Map<Object,Pair<Integer,String>> multiMap = new HashMap<Object,Pair<Integer,String>>();

where the Pair is a parametric class

public class Pair<A, B> {
    A first = null;
    B second = null;

    Pair(A first, B second) {
        this.first = first;
        this.second = second;
    }

    public A getFirst() {
        return first;
    }

    public void setFirst(A first) {
        this.first = first;
    }

    public B getSecond() {
        return second;
    }

    public void setSecond(B second) {
        this.second = second;
    }

}
jfabrizio
  • 760
  • 7
  • 15
13

This is what i found in a similar question's answer

Map<String, List<String>> hm = new HashMap<String, List<String>>();
List<String> values = new ArrayList<String>();
values.add("Value 1");
values.add("Value 2");
hm.put("Key1", values);

// to get the arraylist
System.out.println(hm.get("Key1"));

RESULT: [Value 1, Value 2]

Ryan M
  • 18,333
  • 31
  • 67
  • 74
Neo
  • 1,359
  • 14
  • 34
12

A standard Java HashMap cannot store multiple values per key, any new entry you add will overwrite the previous one.

Andrew Stubbs
  • 4,322
  • 3
  • 29
  • 48
10

Have you got something like this?

HashMap<String, ArrayList<String>>

If so, you can iterate through your ArrayList and get the item you like with arrayList.get(i).

oopbase
  • 11,157
  • 12
  • 40
  • 59
7

I found the blog on random search, i think this will help for doing this: http://tomjefferys.blogspot.com.tr/2011/09/multimaps-google-guava.html

public class MutliMapTest {
public static void main(String... args) {
   Multimap<String, String> myMultimap = ArrayListMultimap.create();

   // Adding some key/value
   myMultimap.put("Fruits", "Bannana");
   myMultimap.put("Fruits", "Apple");
   myMultimap.put("Fruits", "Pear");
   myMultimap.put("Vegetables", "Carrot");

   // Getting the size
   int size = myMultimap.size();
   System.out.println(size);  // 4

   // Getting values
   Collection<String> fruits = myMultimap.get("Fruits");
   System.out.println(fruits); // [Bannana, Apple, Pear]

   Collection<string> vegetables = myMultimap.get("Vegetables");
   System.out.println(vegetables); // [Carrot]

   // Iterating over entire Mutlimap
   for(String value : myMultimap.values()) {
      System.out.println(value);
   }

   // Removing a single value
   myMultimap.remove("Fruits","Pear");
   System.out.println(myMultimap.get("Fruits")); // [Bannana, Pear]

   // Remove all values for a key
   myMultimap.removeAll("Fruits");
   System.out.println(myMultimap.get("Fruits")); // [] (Empty Collection!)
}
}
ozan.yarci
  • 89
  • 1
  • 5
5

Try using collections to store the values of a key:

Map<Key, Collection<Value>>

you have to maintain the value list yourself

zhuwenger
  • 111
  • 4
1

Apache Commons collection classes is the solution.

    MultiMap multiMapDemo = new MultiValueMap();

    multiMapDemo .put("fruit", "Mango");
    multiMapDemo .put("fruit", "Orange");
    multiMapDemo.put("fruit", "Blueberry");

    System.out.println(multiMap.get("fruit"));
   // Mango Orange Blueberry

Maven Dependency

    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -- 
     >
     <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-collections4</artifactId>
         <version>4.4</version>
    </dependency>
Vikas Piprade
  • 272
  • 2
  • 7
1

Apart from all the answers here, I have a solution that I used and found it most useful if you know the length of multiple values to be added to your key.

In my case, it was 2, so I opted for this over a List<string>.

HashMap<String, String[]> multimap= new HashMap<>();
multimap.put("my_key", new String[]{"my_value1", "my_value2"});
JKC
  • 47
  • 8
0

Thinking about a Map with 2 keys immediately compelled me to use a user-defined key, and that would probably be a Class. Following is the key Class:

public class MapKey {
    private Object key1;
    private Object key2;

    public Object getKey1() {
        return key1;
    }

    public void setKey1(Object key1) {
        this.key1 = key1;
    }

    public Object getKey2() {
        return key2;
    }

    public void setKey2(Object key2) {
        this.key2 = key2;
    }
}


// Create first map entry with key <A,B>.
        MapKey mapKey1 = new MapKey();
        mapKey1.setKey1("A");
        mapKey1.setKey2("B");
J.R
  • 2,113
  • 19
  • 21
0

HashMap – Single Key and Multiple Values Using List

Map<String, List<String>> map = new HashMap<String, List<String>>();

  // create list one and store values

    List<String> One = new ArrayList<String>();
    One.add("Apple");
    One.add("Aeroplane");

    // create list two and store values
    List<String> Two = new ArrayList<String>();
    Two.add("Bat");
    Two.add("Banana");

    // put values into map
    map.put("A", One);
    map.put("B", Two);
    map.put("C", Three);
Alwayss Bijoy
  • 778
  • 9
  • 15
0

You can do something like this (add access modifiers as required):

Map<String,Map<String,String>> complexMap=new HashMap<String,Map<String,String>>();

You can insert data like this:

    Map<String,String> componentMap = new HashMap<String,String>();
    componentMap.put("foo","bar");
    componentMap.put("secondFoo","secondBar");
    complexMap.put("superFoo",componentMap);

The Generated Data Structure would be:

{superFoo={secondFoo=secondBar, foo=bar}}

This way each value for the key should have a unique identifier. Also gives O(1) for fetches,if keys are known.

thedeadalive
  • 35
  • 1
  • 6
0

Write a new class that holds all the values that you need and use the new class's object as the value in your HashMap

HashMap<String, MyObject>

class MyObject {
public String value1;
public int value2;
public List<String> value3;
}
George Arokiam
  • 262
  • 2
  • 9
0

Here is the code how to get extract the hashmap into arrays, hashmap that contains arraylist

Map<String, List<String>> country_hashmap = new HashMap<String, List<String>>();

//Creating two lists and inserting some data in it
List<String> list_1 = new ArrayList<String>();
list_1.add("16873538.webp");
list_1.add("16873539.webp");

List<String> list_2 = new ArrayList<String>();
list_2.add("16873540.webp");
list_2.add("16873541.webp");

//Inserting both the lists and key to the Map 
country_hashmap.put("Malaysia", list_1);
country_hashmap.put("Japanese", list_2);

for(Map.Entry<String, List<String>> hashmap_data : country_hashmap.entrySet()){
      String key = hashmap_data.getKey(); // contains the keys
      List<String> val = hashmap_data.getValue(); // contains arraylists
      // print all the key and values in the hashmap
      System.out.println(key + ": " +val);
      
      // using interator to get the specific values arraylists
      Iterator<String> itr = val.iterator();
      int i = 0;
      String[] data = new String[val.size()];
        while (itr.hasNext()){
            String array = itr.next();
            data[i] = array;
            System.out.println(data[i]); // GET THE VALUE
            i++;
        }
  }
HegdeS
  • 69
  • 9
Snowbases
  • 2,316
  • 2
  • 20
  • 26