How to stream a map with collection using Java 8 streams?

微笑、不失礼 提交于 2019-12-04 22:10:18

You can map your Map<String, Collection<Integer>> to List<Map.Entry<String, Integer>>:

data.entrySet().stream()
  .flatMap(e -> e.getValue().stream().map(v -> new HashMap.SimpleEntry<>(e.getKey(), v)))
  .forEach(e -> System.out.printf("key %s val %d%n", e.getKey(), e.getValue()));

or:

data.forEach((k, v) -> v.forEach(n -> System.out.printf("key %s val %d%n", k, n)));

I realize that you ware asking about stream version, but if you are NOT going to use parallelism simplest and probably more efficient option would be using nested loops. This way you can avoid spending time and space on creating temporary instances for each <Key,CollectionItem> pair.

Instead you can use

for (Map.Entry<String, Collection<Integer>> entry : map.entrySet()){
    String key = entry.getKey();
    for (Integer number : entry.getValye()){
        //here we have access to <key, number> pair, 
        //handle them as you wish;
    }
}
Eugene

While this may be a bit obvious, you can also write:

map.forEach((k, v) -> v.forEach(s -> System.out.println(k + "  " + s)))

Example, in Java 9.

Map< String , Collection< Integer > > map =
    Map.ofEntries(
        Map.entry( "alpha" , List.of( 1 , 2 , 3 ) ) ,
        Map.entry( "beta" , List.of( 4 , 5 , 6 ) ) ,
        Map.entry( "gamma" , List.of( 7 , 8 , 9 ) )
    )
;

map.forEach( ( k , v ) -> {
        v.forEach( s -> System.out.println( k + "  " + s ) );
    }
);

Streaming only processes a single value, so you can't get keyValueStream((k,v)-> ...), but you can get keyValueStream(x -> ...) where x is a tuple/pair.

Since you are starting with a Map, which can stream Entry objects (key/value pairs), and you want a key/value pair in your lambda, a stream of Entry objects seems appropriate.

Which means that you just want to flatten the nested collection, e.g. like this:

import java.util.AbstractMap.SimpleEntry;
data.entrySet()
    .stream()
    .flatMap(e -> e.getValue().stream().map(v -> new SimpleEntry<>(e.getKey(), v)))
    // At this point you have a Stream<Entry<String, Integer>> so you can e.g. do this:
    .forEach(e -> System.out.println(e.getKey() + "=" + e.getValue()))
;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!