• Java Stream中map和flatMap方法


    最近看到一篇讲stream语法的文章,学习Javamap()flatMap()方法之间的区别。

    虽然看起来这两种方法都做同样的事情,都是做的映射操作,但实际上差之毫厘谬以千里。

    通过演示Demo中的代码可以了解map()flatMap()的具体功能差异。

    • 首先来一段简单的stream语法foreach方法的用法

    演示Demo:

            List<String> funs = Arrays.asList("F", "U", "N");
            funs.stream().forEach(x -> output(x));
    

    控制台输出:

    INFO-> 当前用户:fv,IP:10.60.192.21,工作目录:/Users/fv/Documents/workspace/fun/,系统编码格式:UTF-8,系统Mac OS X版本:10.15.7
    F
    U
    N
    
    Process finished with exit code 0
    
    

    map方法

    map()是一个中间操作,这意味着它返回Stream对象。

    • 先来一个简单

    演示Demo:

            List<String> funs = Arrays.asList("F", "U", "N");
            funs.stream().map(x->x+"001").forEach(x->output(x));
    

    控制台输出:

    INFO-> 当前用户:fv,IP:10.60.192.21,工作目录:/Users/fv/Documents/workspace/fun/,系统编码格式:UTF-8,系统Mac OS X版本:10.15.7
    INFO-> f
    INFO-> u
    INFO-> n
    INFO-> F001
    INFO-> U001
    INFO-> N001
    java.util.stream.ReferencePipeline$3@27ae2fd0
    java.util.stream.ReferencePipeline$3@29176cc1
    
    Process finished with exit code 0
    
    
    • 再来一个复杂的

    演示Demo:

            List<String> fun1 = Arrays.asList("one", "two", "three");
            List<String> fun2 = Arrays.asList("four", "five", "six");
    
            List<List<String>> nestedList = Arrays.asList(fun1, fun2);
            nestedList.stream().map(x -> {
                return x.stream().map(a -> a.toUpperCase());
            }).forEach(x -> output(x));
            
    

    控制台输出:

    INFO-> 当前用户:fv,IP:10.60.192.21,工作目录:/Users/fv/Documents/workspace/fun/,系统编码格式:UTF-8,系统Mac OS X版本:10.15.7
    INFO-> java.util.stream.ReferencePipeline$3@45018215
    INFO-> java.util.stream.ReferencePipeline$3@30b7c004
    
    

    显然,在最后一步输出的时候,x是一个stream的对象,而不是一个list对象。

    当我们尝试从List<List<String>>获取值进行操作时,map()无法如预期一样工作,需要进行修改才能从嵌套的List<List<String>>对象获取字符串值。

    如下:

            List<String> fun1 = Arrays.asList("one", "two", "three");
            List<String> fun2 = Arrays.asList("four", "five", "six");
    
            List<List<String>> nestedList = Arrays.asList(fun1, fun2);
            nestedList.stream().map(x -> {
                return x.stream().map(a -> a.toUpperCase());
            }).forEach(x ->x.forEach(a->output(a)));
    

    控制台输出:

    INFO-> 当前用户:fv,IP:10.60.192.21,工作目录:/Users/fv/Documents/workspace/fun/,系统编码格式:UTF-8,系统Mac OS X版本:10.15.7
    INFO-> ONE
    INFO-> TWO
    INFO-> THREE
    INFO-> FOUR
    INFO-> FIVE
    INFO-> SIX
    
    Process finished with exit code 0
    

    flatMap方法

    让我们在上述代码中将map()更改为flatMap(),然后查看输出。

    • 先来一个简单

    演示Demo:

            List<String> fun1 = Arrays.asList("one", "two", "three");
            List<String> fun2 = Arrays.asList("four", "five", "six");
            List<List<String>> nestedList = Arrays.asList(fun1, fun2);
            nestedList.stream().flatMap(x -> x.stream()).map(x->x.toUpperCase()).forEach(x -> output(x));
    

    控制台输出:

    INFO-> 当前用户:fv,IP:10.60.192.21,工作目录:/Users/fv/Documents/workspace/fun/,系统编码格式:UTF-8,系统Mac OS X版本:10.15.7
    INFO-> ONE
    INFO-> TWO
    INFO-> THREE
    INFO-> FOUR
    INFO-> FIVE
    INFO-> SIX
    
    Process finished with exit code 0
    
    

    相当于在.flatMap(x -> x.stream())这个时候我们把x.stream()返回的stream对象合并成了一个新的stream对象。这一点在Stream类的方法注释中找到了印证。

    		/**
    		·····
         * @return the new stream
         */
        <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
    

    Java 8 map()与flatMap()

    map()flatMap()方法都可以应用于Stream<T>Optional<T>对象。并且都返回Stream<R>Optional <U>对象。区别在于map()操作为每个输入值生成一个输出值,而flatMap()操作为每个输入值生成任意数量(零个或多个)的输出值。

    flatMap()中,每个输入始终是一个集合,可以是ListSetMap

    map()操作采用一个方法,该方法针对输入流中的每个值调用,并生成一个结果值,该结果值返回至stream

    flatMap()操作采用的功能在概念上消耗一个集合对象并产生任意数量的值。但是在Java中方法返回任意数目的值很麻烦,因为方法只能返回void或一个对象。

    演示Demo:

            List<String> fun1 = Arrays.asList("one", "two", "three");
            List<String> fun2 = Arrays.asList("four", "five", "six");
            Stream.of(fun1,fun2).flatMap(List::stream).forEach(Output::output);
    

    控制台输出:

    INFO-> 当前用户:fv,IP:10.60.192.21,工作目录:/Users/fv/Documents/workspace/fun/,系统编码格式:UTF-8,系统Mac OS X版本:10.15.7
    INFO-> one
    INFO-> two
    INFO-> three
    INFO-> four
    INFO-> five
    INFO-> six
    
    Process finished with exit code 0
    
    

    公众号FunTester首发,原创分享爱好者,腾讯云和掘金社区首页推荐,知乎七级原创作者,欢迎关注、交流,禁止第三方擅自转载。

    FunTester热文精选

  • 相关阅读:
    UWP开发必备:常用数据列表控件汇总比较
    CodeForces 372 A. Counting Kangaroos is Fun
    ubuntu 13.10 eclipse 菜单栏不可用的问题
    Codeforces Round #219(Div. 2)373 B. Making Sequences is Fun(二分+找规律)
    Git/Github使用方法小记
    Ubuntu 下jdk的安装
    VIM简明教程
    codeforces 371 C-Hamburgers
    codeforces 371A K-Periodic Array
    计算机网络中IP地址和MAC地址
  • 原文地址:https://www.cnblogs.com/FunTester/p/13797388.html
Copyright © 2020-2023  润新知