zoukankan      html  css  js  c++  java
  • 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热文精选

  • 相关阅读:
    CDQZ Day5
    CDQZ Day4
    CDQZ Day3
    POJ 2226 Muddy Fields
    【其他】【生成图片】【1】通过phantomjs 进行页面截图
    【Redis】【1】一些报错处理
    【Java】【15】判断url对应的图片是否存在
    【HTML&CSS】【3】点击直接发送邮件
    【微信公众号开发】【16】遇到的问题
    【Oracle】【9】取前N条记录——rownum和row_number() over()的使用
  • 原文地址:https://www.cnblogs.com/FunTester/p/13797388.html
Copyright © 2011-2022 走看看