Recursively Flatten values of nested maps in Java 8
<p>Given a <code>Map&lt;String, Object&gt;</code>, where the values are either a <code>String</code> or another <code>Map&lt;String, Object&gt;</code>, how would one, using Java 8, flatten the maps to a single list of values?</p>

<p>Example:</p>

<pre><code>Map - "key1" -&gt; "value1"
    - "key2" -&gt; "value2"
    - "key3" -&gt; Map - "key3.1" -&gt; "value3.1"
                    - "key3.2" -&gt; "value3.2"
                    - "key3.3" -&gt; Map - "key3.3.1" -&gt; "value3.3.1"
                                      - "key3.3.2" -&gt; "value3.3.2" 
</code></pre>

<p>For the above example, I would like the following list:</p>

<pre><code>value1
value2
value3.1
value3.2
value3.3.1
value3.3.2
</code></pre>

<p>I know it can be done like this:</p>

<pre><code>public static void main(String args[]) throws Exception {
    //Map with nested maps with nested maps with nested maps with nested......
    Map&lt;String, Object&gt; map = getSomeMapWithNestedMaps();

    List&lt;Object&gt; values = new ArrayList&lt;&gt;();
    addToList(map, values);

    for (Object o:values) {
        System.out.println(o);
    }
}

static void addToList(Map&lt;String, Object&gt;map, List&lt;Object&gt; list) {
    for (Object o:map.values()) {
        if (o instanceof Map) {
            addToList((Map&lt;String, Object&gt;)o, list);
        } else {
            list.add(o);
        }
    }
}
</code></pre>

<p>How can I do this with a <code>Stream</code>?</p>

<p>Edit:</p>

<p>After some playing around I figured it out:</p>

<pre><code>public static void main(String args[]) throws Exception {
    //Map with nested maps with nested maps with nested maps with nested......
    Map&lt;String, Object&gt; map = getSomeMapWithNestedMaps();
    //Recursively flatten maps and print out all values
    List&lt;Object&gt; list= flatten(map.values().stream()).collect(Collectors.toList());
}

static Stream&lt;Object&gt; flatten(Stream&lt;Object&gt; stream) {
    return stream.flatMap((o) -&gt;
        (o instanceof Map) ? flatten(((Map&lt;String, Object&gt;)o).values().stream()) : Stream.of(o)
    );
}
</code></pre>