返回首页

Java流Map和FlatMap之间的区别

来源:清一色财经

Java 8为我们提供了使用map和flatMap方法,可以在Stream和Optional上进行元素转换处理,flatMap可以处理Collection数组扁平化。

概述

map和flatMap API源于Java Stream流,在Java8中可以在Optional、Stream和CompletableFuture中找到相关用法。

Stream流表示一系列对象,而Optional表示对象存在或不存在的类,在不同的聚合操作中包括有map和flatMap方法。


(资料图片仅供参考)

Optional使用Map和Flatmap

map方法与Optional配合得很好,比如返回需要的确切类型:

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

使用map会导致嵌套结构,因为map实现会在内部进行额外的包装:

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

正如我们所看到的,最终得到了嵌套结构Optional<Optional<String>。虽然它可以工作,但使用起来相当麻烦,所以最好保持扁平化的结构。

这正是flatMap可以做到的:

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

Streams使用Map和Flatmap

map方法将底层序列封装在Stream实例中,而flatMap方法允许避免嵌套的Stream<Stream<R>>结构。

比如以下例子,map生成一个Stream,该Stream由将toUpperCase方法应用于输入Stream的元素组成:

List myList = Stream.of("a", "b")  .map(String::toUpperCase)  .collect(Collectors.toList());assertEquals(asList("A", "B"), myList);

map在这样一个简单的情况下工作得很好。但是,如果更复杂的比如一个包含多个列表的列表作为输入,让我们看看它是如何工作的:

List> 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]。

flatMap方法首先将输入的多级Stream扁平化为同级Stream,之后,它的工作原理与map方法类似。

结论

Java 8为我们提供了使用map和flatMap方法,可以在Stream和Optional上进行元素转换处理,flatMap可以处理Collection数组扁平化。

标签: