我有以下数据集,键是字符串,值作为值列表。
我想用键和list的每个值作为方法的参数来调用一个方法。迭代所有的键。我可以用两个forEach循环来完成它,如下面的示例所示。我想知道我们是否可以在没有flatMap内环的情况下使用Java8中的流和forEach编写相同的逻辑?谢谢
Map<String,ArrayList<String>> xhashMap ;
if(xhashMap!=null) {
xhashMap.forEach((k,l)-> {
if(k.equals("ax")){
l.forEach(v->{
method1(v,AA.class);
}
}
if(k.equals("bx")){
l.forEach(v->{
method1(v,BB.class);
}
}
});
}
发布于 2017-08-06 15:53:25
无论您使用的是for
循环、forEach
还是Stream
API,都不重要。在所有情况下,您都要在Map
上迭代,以便将每个键与某个值进行比较,这就违背了映射的概念,将键与值关联起来,并提供(通常更好的线性)查找方法。
此外,您应该使用Map<String, List<String>>
,而不是引用像ArrayList
这样的实现类型,而不是首先让它成为null
,而不是让它稍后检查null
。
如果您遵循这些建议,您的代码就会变成
Map<String, List<String>> xhashMap;
// always initialize the map to a non-null reference
xhashMap.getOrDefault("ax", Collections.emptyList())
.forEach(v -> method1(v, AA.class));
xhashMap.getOrDefault("bx", Collections.emptyList())
.forEach(v -> method1(v, BB.class));
如果如变量名所示,映射是一个散列映射,那么两个查找将具有O(1)
时间复杂性,但即使是具有O(log(n))
复杂性的TreeMap
也比遍历映射和比较所有键要好。
只要操作由具有不同参数的唯一方法调用组成,尝试重用公共代码就不会有多大好处,因为共享代码要复杂得多。
发布于 2017-08-04 18:02:06
是的,我们不能用Stream编写它,但是它并不是更好。
由于您执行的是副作用而不是收集结果,所以Stream
本质上是:
xhashMap.entrySet()
.stream()
.forEach(e -> ...);
不幸的是,在forEach
中包含相同的逻辑。
实际上,您甚至可以跳过Stream
创建,因为您可以在不创建Stream
的情况下执行forEach
。
xhashMap.entrySet()
.forEach(e -> ...);
发布于 2017-08-12 12:04:21
当然可以用flatMap和闭包来完成
xHashMap.entrySet().stream()
.flatMap(e -> e.getValue().stream()
.<Runnable>map(v -> () -> {
final String k = e.getKey();
if (k.equals("ax")) {
method1(v, AA.class);
}
if (k.equals("bx")) {
method1(v, BB.class);
}
})
)
.forEach(Runnable::run);
https://stackoverflow.com/questions/45512256
复制相似问题