我想使用Java 8流将带有集合的地图流化。
例如,具有以下数据:
Map<String, Collection<Integer>> data;
我想遍历处理带有相应键字符串的每个整数值的元素。例如:
data.keyValueStream((k,v)-> ...)
任何想法如何实现这一目标?谢谢。
*关于“您为什么需要它?”这个问题,可能有很多原因,我不确定它是否重要。无论如何,我将与您“交流” ...我的特定情况是将所有值(在其特定键下)批量插入数据库。让我们保留一个一般的Java 8流问题...
答案 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;