map()和flatMap()之間的區別

1.概述

map()flatMap() API源自功能語言。在Java 8中,可以在Optional, StreamCompletableFuture (although找到它們CompletableFuture (although名稱稍有不同)。

Streams表示一系列對象,而可選類是表示可以存在或不存在的值的類。除其他聚合操作外,我們還有map()flatMap()方法。

儘管兩者的返回類型相同,但是它們卻截然不同。讓我們通過分析一些流和可選實例來解釋這些差異。

2.可選中的Map和FlatMap

map()方法與Optional一起使用效果很好–如果函數返回的是我們需要的確切類型:

Optional<String> s = Optional.of("test");

 assertEquals(Optional.of("TEST"), s.map(String::toUpperCase));

但是,在更複雜的情況下,我們可能會得到一個返回Optional的函數。在這種情況下,使用map()會導致嵌套結構,因為map()實現會在內部進行附加包裝。

讓我們看另一個例子,以更好地了解這種情況:

assertEquals(Optional.of(Optional.of("STRING")),

 Optional

 .of("string")

 .map(s -> Optional.of("STRING")));

如我們所見,我們最終得到了嵌套結構Optional<Optional<String>>.儘管它可以工作,但是使用起來非常麻煩,並且不提供任何其他的null安全性,因此最好保留平坦的結構。

這正是flatMap()幫助我們完成的工作:

assertEquals(Optional.of("STRING"), Optional

 .of("string")

 .flatMap(s -> Optional.of("STRING")));

3.流中的Map和FlatMap

兩種方法對Optional工作方式相似。

map()方法將基礎序列包裝在Stream實例中,而flatMap()方法允許避免嵌套的Stream<Stream<R>>結構。

在以下示例中, map()生成一個Stream ,該Stream包括將toUpperCase()方法應用於輸入Stream:的元素的結果Stream:

List<String> myList = Stream.of("a", "b")

 .map(String::toUpperCase)

 .collect(Collectors.toList());

 assertEquals(asList("A", "B"), myList);

map()在這種簡單的情況下工作得很好,但是如果我們有更複雜的內容(例如將列表作為輸入)怎麼辦。

讓我們看看它是如何工作的:

List<List<String>> list = Arrays.asList(

 Arrays.asList("a"),

 Arrays.asList("b"));

 System.out.println(list);

此摘要打印列表[[a], [b]].
現在,讓我們使用flatMap()

System.out.println(list

 .stream()

 .flatMap(Collection::stream)

 .collect(Collectors.toList()));

這樣的代碼片段的結果將被展平為[a, b].

TflatMap()方法首先展平了輸入StreamStreamsStreamStrings (用於更多關於壓扁,參見文章)。此後,它的工作方式類似於map()方法。

4。結論

Java 8使我們有機會使用最初在函數式語言中使用的map()flatMap()方法。

我們可以在Streams和Optionals上調用它們。這些方法通過應用提供的映射功能幫助我們獲取映射對象。

與往常一樣,您可以在GitHub上查看本文提供的示例。