Jason Fingar
Jason Fingar

Reputation: 3368

Iterate over nested (multi-dimensional) hashmap

I have a HashMap<String, Object> that looks like this when I call .toString() on it:

{somekey=false, anotherKey=someString, thirdKey={nestedKey=hello, nestedKey2=world,etc=etcetcetc}}

At a certain point in my script, I would like to iterate over the "thirdKey" set as its own map. Is there a common convention used to isolate a "nested" HashMap and use it as its own one-dimensional map?

Upvotes: 2

Views: 6612

Answers (4)

Sanyam
Sanyam

Reputation: 1

public static Map<String, Object> flatten(Map<String, Object> map) {
    Map<String, Object> newMap = new HashMap<>();
    for (Entry<String, Object> entry : map.entrySet()) {
        if (entry.getValue() instanceof Map) {
            @SuppressWarnings("unchecked")
            Map<String, Object> tempMap = flatten((HashMap<String, Object>) entry.getValue());
            for (Entry<String, Object> tempEntry : tempMap.entrySet()) {
                newMap.put(entry.getKey()+"."+tempEntry.getKey(), tempEntry.getValue());
            }
        } else {
            newMap.put(entry.getKey(), entry.getValue());
        }
    }
    return newMap;
}

Upvotes: 0

Janis K.
Janis K.

Reputation: 316

Here's my code for recursively extracting all values from the map (and the maps within these map).

public List<Object> getValues(Map<String, Object> map) {

    List<Object> retVal = new ArrayList<Object>();

    for (Map.Entry<String, Object> entry : map.entrySet()) {
        Object value = entry.getValue();

        if (value instanceof Map) {
            retVal.addAll(getValues((Map) value));
        } else {
            retVal.add(value);
        }
    }

    return retVal;
}

As Vikdor already said, I don't think there is a real convention for this.

Edit: You could, of course, also write the keys and values into a new Map ("flattening" it). I just added the values to a List, because this way you don't run into problems when one of the nested maps uses an already present key.

Upvotes: 6

Bohemian
Bohemian

Reputation: 425398

No convention I'm aware of. You have to fall back to instanceof to see if the value at the key is a Map, and treat it specially if it is - in your case recursively.

Upvotes: 3

Vikdor
Vikdor

Reputation: 24134

I doubt if there would be a "common convention" with generics in place. It's best to move towards strongly typed programs and not use Object as either key or value of a hashmap. Then this scenario won't be encountered and one would have more organized data definitions. My two cents!

Upvotes: 1

Related Questions