64

I have following LinkedHashMap declaration.

LinkedHashMap<String, ArrayList<String>> test1

my point is how can i iterate through this hash map. I want to do this following, for each key get the corresponding arraylist and print the values of the arraylist one by one against the key.

I tried this but get only returns string,

String key = iterator.next().toString();  
ArrayList<String> value = (ArrayList<String> )test1.get(key)
Craig P. Motlin
  • 26,452
  • 17
  • 99
  • 126
P basak
  • 4,874
  • 11
  • 40
  • 63
  • LinkedHashMap is used for preserving ordering. The question, nor the responses are mentionning ordering. Please replace LinkedHashMap by HashMap. This is very confusing – apflieger May 13 '20 at 07:49

5 Answers5

159
for (Map.Entry<String, ArrayList<String>> entry : test1.entrySet()) {
    String key = entry.getKey();
    ArrayList<String> value = entry.getValue();
    // now work with key and value...
}

By the way, you should really declare your variables as the interface type instead, such as Map<String, List<String>>.

matt b
  • 138,234
  • 66
  • 282
  • 345
  • 3
    btw, I want to have the list with the insertion order, i used hashmap before but it messed up the order. – P basak Sep 07 '12 at 02:34
  • 4
    I'm not saying don't use `LinkedHashMap` - but typically best practice is to declare things like `Map> map = new LinkedHashMap>`. – matt b Sep 07 '12 at 02:36
  • 1
    @Pbasak You only use the interface type for the declaration. When you instantiate the map object you will still use your `LinkedHashMap` which will make sure that the insertion order stays the same. This way you stick with your choice of implementation but still use the more general type to the outside. – Konrad Reiche Sep 07 '12 at 02:38
  • 32
    Why is the order guaranteed when entrySet returns a set? I know order is guaranteed in the LinkedHashMap, but the docs say the iterator of a set makes no guarantee on order – Jonathan. Dec 07 '14 at 13:31
  • 2
    Why did you keep ArrayList in the declarations, then? –  Jan 05 '16 at 13:42
  • 3
    @Jonathan., good question. Better late than never: see the answer at http://stackoverflow.com/a/2924143/423105 – LarsH Jun 02 '16 at 22:04
15

I'm assuming you have a typo in your get statement and that it should be test1.get(key). If so, I'm not sure why it is not returning an ArrayList unless you are not putting in the correct type in the map in the first place.

This should work:

// populate the map
Map<String, List<String>> test1 = new LinkedHashMap<String, List<String>>();
test1.put("key1", new ArrayList<String>());
test1.put("key2", new ArrayList<String>());

// loop over the set using an entry set
for( Map.Entry<String,List<String>> entry : test1.entrySet()){
  String key = entry.getKey();
  List<String>value = entry.getValue();
  // ...
}

or you can use

// second alternative - loop over the keys and get the value per key
for( String key : test1.keySet() ){
  List<String>value = test1.get(key);
  // ...
}

You should use the interface names when declaring your vars (and in your generic params) unless you have a very specific reason why you are defining using the implementation.

Eric B.
  • 23,425
  • 50
  • 169
  • 316
  • 1
    Hi i used linkhashmap to keep the elements in insertion order. – P basak Sep 07 '12 at 02:35
  • Sure - but you can specify LinkedHashMap when creating the instance. However, using the interface name for the variable allows you to make the code implementation independent. ie: you can easily replace the implementation with something else at a later point without needing to recode everything. See my example above for the declaration using the interface as the var, and the LinkedHashMap for the implementation. – Eric B. Sep 07 '12 at 02:38
12

In Java 8:

Map<String, List<String>> test1 = new LinkedHashMap<String, List<String>>();
test1.forEach((key,value) -> {
    System.out.println(key + " -> " + value);
});
JonDoe297
  • 1,601
  • 1
  • 15
  • 21
8

You can use the entry set and iterate over the entries which allows you to access both, key and value, directly.

for (Entry<String, ArrayList<String>> entry : test1.entrySet()) {
     System.out.println(entry.getKey() + "/" + entry.getValue());
}

I tried this but get only returns string

Why do you think so? The method get returns the type E for which the generic type parameter was chosen, in your case ArrayList<String>.

Konrad Reiche
  • 27,743
  • 15
  • 106
  • 143
7
// iterate over the map
for(Entry<String, ArrayList<String>> entry : test1.entrySet()){
    // iterate over each entry
    for(String item : entry.getValue()){
        // print the map's key with each value in the ArrayList
        System.out.println(entry.getKey() + ": " + item);
    }
}
Mark Elliot
  • 75,278
  • 22
  • 140
  • 160