Java - Java 8中新出現的map()和flatMap()差別結論


一開始讀Lambda時,有點難進入狀況,畢竟Java是OOP語言,而Lambda為偏FP語言。後來,卻開始連結到以前學過的JavaScript Promise或callback等用法,其中講到Function和Monad,更想到以前學過的一些些PureScript概念。當然也想起C#中一些Validator的pipeline寫法,或是撈sql時用的Lambda語法。才驚覺自己又在程式學習路上更進步了一些,有時對不同語言是互通的事實還是覺得滿有趣的。


回到正題,

Java 8中新出現的map()和flatMap()差別,經過一番思考和比較後,得到以下結論:

  • map()的input和output之間的對映就像「一個蘿蔔一個坑」的轉換,e.g. 將int[] array = {1, 2, 3}分別轉成 String[] array = {“1”, “2”, “3”}。 
  • 而flatMap()則能有「一對多(one to many)」的轉換能力。e.g. 將一個訂單(這裡是一個)中所有產品項目(這裡已轉換成多個)取出,再將每個產品中的所有贈品名稱取出,並將最後結果輸出到一個list(注意,這裡的輸出不像map()是一個蘿蔔一個坑,而是任意想定義的輸出)中。 
=> 如果從寫程式的角度再看一次上述例子: 其實flatMap()幫我們省掉很多巢狀迴圈。以前要取得所有產品項目的所有贈品名稱,必須透過兩個for loop達成。這也是為何flatMap()不等於map()的主因之一。


另外,
map()和flatMap()都具有將「A型態轉成B型態」能力。但差別是:如果今天某XX函式不是回傳Optional型態,而有null可能性的話,那map()是有能力持續處理null的情形(見註一),因而這情形就不該使用flatMap()。(例子詳見參考來源:Optional 與 Stream 的 flatMap)

註一:
因flatMap()實作上,當值存在時,會是return Objects.requireNonNull(mapper.apply(value));

而map()實作上,當值存在時,會是return Optional.ofNullable(mapper.apply(value))。


以上結論整理的資料來源參考自:(想知道更多細節可見連結)
flatMap() Java API: https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#flatMap-java.util.function.Function-

map() Java API: https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#map-java.util.function.Function-

Difference Between map() and flatMap() in Java: https://www.techiedelight.com/difference-map-flatmap-java/

What's the difference between map and flatMap methods in Java 8? https://stackoverflow.com/questions/26684562/whats-the-difference-between-map-and-flatmap-methods-in-java-8

Optional 與 Stream 的 flatMap
https://openhome.cc/Gossip/Java/FlatMap.html

留言

熱門文章