如何使用Java 8流以集合方式流式传输地图?

时间:2018-09-16 18:07:11

标签: java dictionary java-8 java-stream multimap

我想使用Java 8流将带有集合的地图流化。

例如,具有以下数据:

Map<String, Collection<Integer>> data;

我想遍历处理带有相应键字符串的每个整数值的元素。例如:

data.keyValueStream((k,v)-> ...)

任何想法如何实现这一目标?谢谢。

*关于“您为什么需要它?”这个问题,可能有很多原因,我不确定它是否重要。无论如何,我将与您“交流” ...我的特定情况是将所有值(在其特定键下)批量插入数据库。让我们保留一个一般的Java 8流问题...

4 个答案:

答案 0 :(得分:5)

您可以将Map<String, Collection<Integer>>映射到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()));

或:

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

答案 1 :(得分:3)

我意识到您会询问流版本,但是如果您不打算使用并行性,最简单且可能更有效的选择是使用嵌套循环。这样,您可以避免花费时间和空间来为每个<Key,CollectionItem>对创建临时实例。

相反,您可以使用

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;
    }
}

答案 2 :(得分:2)

虽然这可能有点明显,但您也可以这样写:

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

示例,在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 ) );
    }
);

答案 3 :(得分:1)

流仅处理单个值,因此您无法获得keyValueStream((k,v)-> ...),但可以获得keyValueStream(x -> ...),其中x是元组/对。

由于您以Map开头,该流可以传输Entry个对象(键/值对),并且您想要在lambda中使用键/值对,因此{{1} }对象似乎合适。

这意味着您只想展平嵌套的集合,例如像这样:

Entry
import java.util.AbstractMap.SimpleEntry;