java8 map()和flatMap()之间的区别

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

猜你喜欢

转载自blog.csdn.net/niugang0920/article/details/115358700