1.概述
map()和flatMap() 在Java 8中,可以在Optional,Stream和CompletableFuture中找到它们(尽管名称稍有不同)。
流表示一系列对象,而可选类是表示可以存在或不存在的值的类。 除其他聚合操作外,还有map()和flatMap()方法。
尽管两者的返回类型相同,但是它们却截然不同。
2.Map 和Flatmap 在 Optionals
map()方法与Optional一起使用效果很好-如果函数返回的是需要的确切类型:
@Test
public void test2(){
Optional<String> s = Optional.of("test");
assertEquals(Optional.of("TEST"), s.map(String::toUpperCase));
}
但是,在更复杂的情况下,可能会得到一个返回Optional的函数。 在这种情况下,使用map()会导致嵌套结构,因为map()实现会在内部进行附加包装。
看另一个例子:
@Test
public void test3() {
assertEquals(Optional.of(Optional.of("STRING")),
Optional
.of("string")
.map(s -> Optional.of("STRING")));
}
可以看到,嵌套结构Optional.of(Optional.of(“STRING”)。 尽管它可以使用,但是使用起来非常麻烦,并且不提供任何附加的null安全性,因此最好保留平坦的结构。
flatMap()使用
@Test
public void test4() {
assertEquals(Optional.of("STRING"), Optional
.of("string")
.flatMap(s -> Optional.of("STRING")));
}
3.Map 和Flatmap 在 Streams
两种方法对于Optional的使用方式相似。
map()方法将基础序列包装在Stream实例中,而flatMap()方法允许避免嵌套的Stream <Stream >结构。
在这里,map()生成一个Stream,该Stream包括将toUpperCase()方法应用于输入Stream的元素的结果:
@Test
public void test5() {
List<String> myList = Stream.of("a", "b")
.map(String::toUpperCase)
.collect(Collectors.toList());
assertEquals(asList("A", "B"), myList);
}
在这种简单的情况下,map()可以很好地使用。 但是,如果有更复杂的东西,例如List放List,该怎么办?
@Test
public void test6() {
List<List<String>> list = Arrays.asList(
Arrays.asList("a"),
Arrays.asList("b"));
System.out.println(list);//[[a], [b]]
System.out.println(list
.stream()
.flatMap(Collection::stream)
.collect(Collectors.toList()));//[a, b]
}
这样的代码片段的结果将被展平为[a,b]。