map()和flatMap()之間的區別
1.概述
map()
和flatMap()
API源自功能語言。在Java 8中,可以在Optional, Stream
和CompletableFuture (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].
T
他flatMap()
方法首先展平了輸入Stream
的Streams
的Stream
的Strings
(用於更多關於壓扁,參見文章)。此後,它的工作方式類似於map()
方法。
4。結論
Java 8使我們有機會使用最初在函數式語言中使用的map()
和flatMap()
方法。
我們可以在Streams
和Optionals上調用它們。這些方法通過應用提供的映射功能幫助我們獲取映射對象。
與往常一樣,您可以在GitHub上查看本文提供的示例。