Java流Map和FlatMap之間的區(qū)別
概述
map和flatMap API源于Java Stream流,在Java8中可以在Optional、Stream和CompletableFuture中找到相關(guān)用法。
Stream流表示一系列對象,而Optional表示對象存在或不存在的類,在不同的聚合操作中包括有map和flatMap方法。
Optional使用Map和Flatmap
map方法與Optional配合得很好,比如返回需要的確切類型:
Optional<String> s = Optional.of("test");
assertEquals(Optional.of("TEST"), s.map(String::toUpperCase));
使用map會(huì)導(dǎo)致嵌套結(jié)構(gòu),因?yàn)閙ap實(shí)現(xiàn)會(huì)在內(nèi)部進(jìn)行額外的包裝:
assertEquals(Optional.of(Optional.of("STRING")),
Optional
.of("string")
.map(s -> Optional.of("STRING")));
正如我們所看到的,最終得到了嵌套結(jié)構(gòu)Optional<Optional<String>。雖然它可以工作,但使用起來相當(dāng)麻煩,所以最好保持扁平化的結(jié)構(gòu)。
這正是flatMap可以做到的:
assertEquals(Optional.of("STRING"), Optional
.of("string")
.flatMap(s -> Optional.of("STRING")));
Streams使用Map和Flatmap
map方法將底層序列封裝在Stream實(shí)例中,而flatMap方法允許避免嵌套的Stream<Stream<R>>結(jié)構(gòu)。
比如以下例子,map生成一個(gè)Stream,該Stream由將toUpperCase方法應(yīng)用于輸入Stream的元素組成:
List<String> myList = Stream.of("a", "b")
.map(String::toUpperCase)
.collect(Collectors.toList());
assertEquals(asList("A", "B"), myList);
map在這樣一個(gè)簡單的情況下工作得很好。但是,如果更復(fù)雜的比如一個(gè)包含多個(gè)列表的列表作為輸入,讓我們看看它是如何工作的:
List<List<String>> list = Arrays.asList(
Arrays.asList("a"),
Arrays.asList("b"));
System.out.println(list);
此片段打?。篬[a],[b]]
現(xiàn)在讓我們使用flatMap:
System.out.println(list
.stream()
.flatMap(Collection::stream)
.collect(Collectors.toList()));
片段的結(jié)果將被扁平化為[a,b]。
flatMap方法首先將輸入的多級Stream扁平化為同級Stream,之后,它的工作原理與map方法類似。
結(jié)論
Java 8為我們提供了使用map和flatMap方法,可以在Stream和Optional上進(jìn)行元素轉(zhuǎn)換處理,flatMap可以處理Collection數(shù)組扁平化。