3

I have a HashMap, which contains another HashMap. I want to iterate over the first HashMap and use the Key values from that. Then, as I iterate over the first HashMap I want to start an inner loop iterating over the second HashMap, getting all the values.

The problem I have so far is that I can't figure out how to get the keys from the Iterator.

HashMap<String, HashMap<Integer, String>> subitems = myHashMap.get("mainitem1");

Collection c = subitems.values();
Iterator itr = c.iterator();

while(itr.hasNext())
{
    // Get key somehow? itr.getKey() ???

    // contains the sub items
    HashMap productitem = (HashMap)itr.next();
}

The data that i get from subitems is this:

{Item1{0=sub1, 1=sub2}, Item2{0=sub3, 1=sub4}}

Then, in the while loop productitem contains the 'sub items'. But i can't find out where i can get the key value 'Item1' and 'Item2' from.

How can i get those?

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
w00
  • 26,172
  • 30
  • 101
  • 147
  • In addition to using `entrySet()` as per the answers below, you can also use `keySet()` to get just the keys. –  Jul 25 '12 at 08:38

5 Answers5

9

You can't get the key from values().iterator().

You need to use entrySet().iterator(). That will return Map.Entry<K,V> objects on which you can call getKey() and getValue().

for (Map.Entry<Integer,Key> entry : subitems.keySet()) {
  Integer key = entry.getKey();
  String value = entry.getValue();

  // do stuff
}

I'd also like to add that having deeply nested maps of lists of maps is usually a sign that you really want to write custom classes to hold your data. Especially when the maps have pre-defined keys to be used and interpretation of the values in the lists depends on the position within the list! I call this code smell "object denial".

Community
  • 1
  • 1
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
3

You can't go from value to key in a map. (There may be several keys mapping to the same value!)

You can iterate over the map entries though using subitems.entrySet().iterator(), or you can iterate over the keys, and in each iteration retrieve the associated value through subitems.get(key).

aioobe
  • 413,195
  • 112
  • 811
  • 826
  • I'd discourage iterating over the keys and calling `get()`, because it will almost certainly have worse performance than iterating over the keyset. – Joachim Sauer Jul 25 '12 at 08:38
  • Ok. I think the code is slightly cleaner though, but that's a matter of taste perhaps. – aioobe Jul 25 '12 at 08:39
3

You could do something like this (using iterators):

Set<Entry<String, HashMap<Integer, String>>> c = subitems.entrySet();
Iterator<Entry<String, HashMap<Integer, String>>> iterator = c.iterator();

while(iterator.hasNext())
{
    Entry<String, HashMap<Integer, String>> entry = iterator.next();
    System.out.println("key:" + entry.getKey());
    HashMap<Integer, String> innerMap = entry.getValue();
    if (innerMap == null) {
        continue;
    }
    Iterator<Entry<Integer, String>> innerIterator = innerMap.entrySet().iterator();
    while (innerIterator.hasNext()) {
        Entry<Integer, String> innerEntry = innerIterator.next();
        System.out.println("key:" + innerEntry.getKey() + " value: " + innerEntry.getValue());
    }
}

or like this using foreach structure:

for (Entry<String, HashMap<Integer,String>> entry : subitems.entrySet())
{
    System.out.println("key:" + entry.getKey());
    HashMap<Integer, String> innerMap = entry.getValue();
    if (innerMap == null) {
        continue;
    }
    for (Entry<Integer, String> innerEntry : innerMap.entrySet())
        System.out.println("key:" + innerEntry.getKey() + " value: " + innerEntry.getValue());
    }
}
Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
2

java Collections provide facility of EntrySet. This is a list of objects which contain individual keys and values as its properties. You can take a iterator out of this list.

You can get keys as follows.

Iterator i= subitems.entrySet().iterator();

while(i.hasNext()){

String key= i.next().getkey();
}
Ahmad
  • 2,110
  • 5
  • 26
  • 36
1

You can iterate over entries using entrySet().iterator() on the first HashMap or get the keys and iterate over them: Instead of subitems.values().iterator() use subitems.keys().iterator() and use the next key to get the inner hashmap.

Aleks G
  • 56,435
  • 29
  • 168
  • 265