java8流图在这里做了什么?

Sin*_*ang 7 java sorting java-8 java-stream

我对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);
Run Code Online (Sandbox Code Playgroud)

我在这里得到了空输出,但如果我改变地图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);
Run Code Online (Sandbox Code Playgroud)

我可以得到

{1 = 1,2 = 2}

为什么它只是没有运行map()方法?他们之间有什么区别?

Era*_*ran 21

strings.stream().map(s->map.put(s, s));
Run Code Online (Sandbox Code Playgroud)

什么也不做,因为在您执行终端操作之前不会处理流管道.因此,Map遗体是空的.

将终端操作添加到流管道将导致map.put(s, s)Stream终端操作所需的每个元素执行(一些终端操作仅需要一个元素,而其他操作则需要所有元素Stream).

另一方面,第二个流管道:

strings.stream().forEach(s->map.put(s, s));
Run Code Online (Sandbox Code Playgroud)

以终端操作结束 - forEach- 为每个元素执行Stream.

也就是说,两个片段都在滥用Stream.为了填充CollectionMap基于其内容Stream,您应该使用collect(),可以创建一个Map或一个Collection并填充它,无论您喜欢什么.forEachmap有不同的目的.

例如,要创建一个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);
Run Code Online (Sandbox Code Playgroud)


Gho*_*ica 7

区别在于:

  • 想法forEach()是在底层集合的每个元素上"工作"(通过产生副作用),而
  • map()是关于在每个对象上应用一个方法并将其结果放入一个新流

这也是你stream().map()不会产生某些东西的原因- 因为你扔掉map()通话产生的新流!

从这个意义上说,这两种方法的签名告诉你:

void forEach(BiConsumer<? super K,? super V> action)
Run Code Online (Sandbox Code Playgroud)

对此映射中的每个条目执行给定操作,直到处理完所有条目

 <R> Stream<R> map(Function<? super T,? extends R> mapper)
Run Code Online (Sandbox Code Playgroud)

返回一个流,该流包含将给定函数应用于此流的元素的结果.

并且为了记录:只有map()一个方法 - forEach()存在于两者,流和集合/ Iterables.