java8流图在这里做了什么?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
我在这里得到了空输出,但如果我将地图更改为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()
方法?他们之间有什么区别?
strings.stream().map(s->map.put(s, s));
什么也不做,因为在您执行终端操作之前不会处理流管道。因此,Map
仍然是空的。
将终端操作添加到流管道将导致对终端操作所需的map.put(s, s)
的每个元素执行Stream
(某些终端操作只需要一个元素,而其他操作则需要Stream
的所有元素)。
另一方面,第二个流管道:
strings.stream().forEach(s->map.put(s, s));
以终端操作结束 - forEach
- 为Stream
的每个元素执行。
也就是说,两个片段都在滥用Stream
s。为了根据Collection
的内容填充Map
或Stream
,你应该使用collect()
,它可以创建一个Map
或Collection
并填充它,但你喜欢。 forEach
和map
有不同的目的。
例如,要创建Map
:
List<String> strings = Lists.newArrayList("1", "2");
Map<String, String> map = strings.stream()
.collect(Collectors.toMap(Function.identity(),
Function.identity()));
System.out.println(map);
区别在于:
forEach()
的想法是在底层集合的每个元素上“工作”(通过产生副作用),而map()
是关于在每个对象上应用方法并将其结果放入新流中
这也是你的stream().map()
没有产生某些东西的原因 - 因为你扔掉了由map()
调用创建的新流!
从这个意义上说,这两种方法的签名告诉你:
void forEach(BiConsumer<? super K,? super V> action)
对此映射中的每个条目执行给定操作,直到处理完所有条目
与
<R> Stream<R> map(Function<? super T,? extends R> mapper)
返回一个流,该流包含将给定函数应用于此流的元素的结果。
并且为了记录:只有map()
是流方法 - forEach()
存在于两者,流和集合/ Iterables。
Stream
的每个实例方法的文档都说明该方法是中间操作还是终端操作。只有终端操作才会导致对流进行评估。除非下游终端操作需要,否则可以不执行中间操作。
这可以提高效率,特别是当终端操作是短路操作时,例如findAny()
。在找到匹配元素之后,不需要为其他元素执行具有复杂中间操作集的管道。
在你的情况下,forEach()
是一个终端操作;它导致管道被执行。 map()
是一个中间操作;除非下游终端操作需要,否则它不需要做任何事情。
你应该用
stream().collect(Collectors.toMap(s -> s,s -> s)
...或者沿着这些方向的东西,而不是stream().map(...)
以上是关于java8流图在这里做了什么?的主要内容,如果未能解决你的问题,请参考以下文章