2017-08-08 100 views
5

我對java8流中map()forEach()方法之間的區別感到困惑。例如,java8流映射在這裏做什麼?

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()方法?他們有什麼區別?

回答

16
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。爲了根據Stream的內容填充CollectionMap,您應該使用collect(),它可以創建MapCollection並根據您的喜好填充它。 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); 
7

所不同的是這樣的:

  • 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。

-1

您應該使用

stream().collect(Collectors.toMap(s -> s,s -> s)

...或者類似的規定,而不是stream().map(...)