java8流映射在这里做什么?
我对java8流中map()
和forEach()
方法之间的区别感到困惑。比如说,
List<String> strings = Lists.newArrayList("1", "2");
Map<String, String> map = Maps.newHashMap();
strings.stream().map(s->map.put(s, s));
System.out.println(map);
我在这里得到了空输出,但是如果我将map更改为forEach()
,就像
List<String> strings = Lists.newArrayList("1", "2");
Map<String, String> map = Maps.newHashMap();
strings.stream().forEach(s->map.put(s, s));
System.out.println(map);
我可以
{1=1, 2=2}
为什么它不运行map()
方法?他们之间有什么区别
# 1 楼答案
你应该使用
stream().collect(Collectors.toMap(s -> s,s -> s)
。。。或者类似的东西,而不是
stream().map(...)
# 2 楼答案
不执行任何操作,因为在执行终端操作之前不会处理流管道。因此
Map
仍然是空的将终端操作添加到流管道将导致对终端操作所需的
map.put(s, s)
的每个元素执行Stream
(一些终端操作只需要一个元素,而另一些终端操作需要Stream
的所有元素)另一方面,第二条流管道:
以终端操作
forEach
结束,该操作针对Stream
的每个元素执行也就是说,这两个代码段都误用了
Stream
。为了基于Stream
的内容填充Collection
或Map
,您应该使用collect()
,它可以创建Map
或Collection
并按您喜欢的方式填充它forEach
和map
有不同的目的例如,要创建
Map
,请执行以下操作:# 3 楼答案
{}的每个实例方法的文档说明了该方法是中间操作还是终端操作。只有终端操作才会导致对流进行评估。除非下游终端操作要求,否则不得执行中间操作
这可以提高效率,特别是当终端操作是短路操作时,例如
findAny()
。在找到匹配的元素后,不需要对其他元素执行具有复杂中间操作集的管道在您的例子中,
forEach()
是一个终端操作;它导致执行管道map()
是一种中间操作;它不需要做任何事情,除非下游终端操作需要# 4 楼答案
区别在于:
map()
是对每个对象应用一个方法,并将该方法的结果放入一个新的流中这也是你的
stream().map()
没有产生结果的原因——因为你扔掉了map()
调用创建的新流从这个意义上讲,这两种方法的签名告诉您:
对
请注意:只有
map()
是一个流方法-forEach()
同时存在于流和集合/Iterables中