java8中 map和flatmap的共同點和區別,以及兩者的實例解析

在函數式語言中,函數作爲一等公民,可以在任何地方定義,在函數內或函數外,可以作爲函數的參數和返回值,可以對函數進行組合。由於命令式編程語言也可以通過類似函數指針的方式來實現高階函數,函數式的最主要的好處主要是不可變性帶來的。沒有可變的狀態,函數就是引用透明(Referential transparency)的和沒有副作用(No Side Effect)。 

任何一種函數式語言中,都有map函數與faltMap這兩個函數,比如python雖然不是純函數式語言,也有這兩個函數。再比如在jdk1.8之後,也加入了Lambda表達式,自然也支持map函數。

上海尚學堂java培訓在這文章中就着重介紹下Map和faltMap
 

一、map和faltMap的共同點和區別

1、共同點

  •  都是依賴FuncX(入參,返回值)進行轉換(將一個類型依據程序邏輯轉換成另一種類型,根據入參和返回值)
  •  都能在轉換後直接被subscribe

2、區別

  • map返回的是結果集,flatmap返回的是包含結果集的Observable(返回結果不同)
  • map被訂閱時每傳遞一個事件執行一次onNext方法,flatmap多用於多對多,一對多,再被轉化爲多個時,一般利用from/just進行一一分發,被訂閱時將所有數據傳遞完畢彙總到一個Observable然後一一執行onNext方法(執行順序不同)>>>>(如單純用於一對一轉換則和map相同)
  • map只能單一轉換,單一隻的是隻能一對一進行轉換,指一個對象可以轉化爲另一個對象但是不能轉換成對象數組(map返回結果集不能直接使用from/just再次進行事件分發,一旦轉換成對象數組的話,再處理集合/數組的結果時需要利用for一一遍歷取出,而使用RxJava就是爲了剔除這樣的嵌套結構,使得整體的邏輯性更強。)
  • flatmap既可以單一轉換也可以一對多/多對多轉換,flatmap要求返回Observable,因此可以再內部進行from/just的再次事件分發,一一取出單一對象(轉換對象的能力不同)

 

二、實例

假如我們有這樣一個需求給定單詞列表["Hello","World"],你想要返回列表["H","e","l", "o","W","r","d"],
對於這樣的需求,我們可能想到的第一個版本可能是這樣子的:

words.stream()
.map(word -> word.split(""))
.distinct()
.collect(toList());

這個方法的問題在於,傳遞給map方法的Lambda爲每個單詞返回了一個String[](String
列表)。因此, map 返回的流實際上是Stream 類型的。你真正想要的是用
Stream來表示一個字符流。因此,這是行不通的。

以下是我對這個問題的解法和分步寫法,希望能對你有幫助:

 

 1  String ss = "Hello";
 2 
 3         String[] aa = ss.split("");
 4 
 5         String[] bb = {"H", "e", "l", "l", "o"};
 6 
 7 
 8         String[] strings = {"Hello", "World"};
 9 
10         //Arrays.stream接收一個數組返回一個流
11         List> streamList = Arrays.asList(strings).stream().
12                 map(str -> str.split("")).
13                 map(str -> Arrays.stream(str)).
14                 collect(Collectors.toList());
15 
16         //分步寫(map)
17 
18         Stream stream = Arrays.asList(strings).stream().
19                 map(str -> str.split(""));
20 
21         Stream> streamStream = stream.map(strings1 -> Arrays.stream(strings1));
22         List> streamList1 = streamStream.collect(Collectors.toList());
23 
24 
25         List stringList = Arrays.asList(strings).stream().
26                 map(str -> str.split("")).
27                 flatMap(str -> Arrays.stream(str))
28                 .collect(Collectors.toList());
29 
30 
31         //分步寫(流只能消費一次)(flatMap)
32         Stream stream1 = Arrays.asList(strings).stream().
33                 map(str -> str.split(""));
34 
35         Stream stringStream = stream1.flatMap(strings1 -> Arrays.stream(strings1));
36 
37         List stringList1 = stringStream.collect(Collectors.toList());

       對flatMap的說明:這個在這裏的主要作用是對流進行扁平化

 

 

三、最後總結

現在簡單說說scala中這兩個函數的用法。有一種觀點認爲將map和flatMap說成Scala函數機制的核心都不爲過分,其實是有一定道理的。因爲實際中我們使用最多的場景就是對數據進行map操作或者flatMap操作。

map函數的用法,顧名思義,將一個函數傳入map中,然後利用傳入的這個函數,將集合中的每個元素處理,並將處理後的結果返回。而flatMap與map唯一不一樣的地方就是傳入的函數在處理完後返回值必須是List,其實這也不難理解,既然是flatMap,那除了map以外必然還有flat的操作,所以需要返回值是List才能執行flat這一步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章