我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java中stream处理中map与flatMap的比较和使用案例

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java中stream处理中map与flatMap的比较和使用案例

前言

使用Java8的新特性Stream流式处理,可以提高对于集合的一些操作效率,再配合lambda表达式,可以极致的简化代码,尤其还有并行流这个东东,可以去 了解一下,在一些场合还是可以提高效率的,而且编码起来也不费事。

并且流式处理的核心就是一个浅拷贝和引用管道,其内部实现了一个引用管道ReferencePipeline, 他把需要处理的数据的引用拷贝了一份,然后处理数据,最后收集结果也是将这些引用放到了另一个集合中。

今天要讲的就是stream处理中的map和flatMap这俩个的比较和使用

共同点和区别

首先看一下源代码


  <R> Stream<R> map(Function<? super T, ? extends R> mapper);
   <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

共同点

  • 都是依赖stream进行转换,结合lambda的入参和返回值,将一个类型依据程序逻辑转换成另一种类型。
  • 最后结果返回都还是一个流,还可以对其进行继续的流式处理或者进行收集。

区别

  • 方法参数不同,第一个参数是一样的,但是第二个不一样,对于map第二个参数没啥要求,但是使用flatMap时,第二个参数还得用流来接收。
  • 所以flatMap多用于多对多,一对多,也就是map是将一个数据流中的一个数据节点,映射成另外一个数据节点,而flatMap是将一个数据流中的一个数据节点映射成另外一个数据流,这个另外的数据流可以是一个数据节点也可以是多个数据节点。
  • flatmap既可以单一转换也可以一对多/多对多转换,flatmap要求返回Observable,因此可以再内部进行from/just的再次事件分发,一一取出单一对象(转换对象的能力不同)

使用案例

比如我们使用map将一个per对象映射成一个字符串对象


  static class Per {
    public String name;
    public int age;

    public Per(String name, int age) {
      this.name = name;
      this.age = age;
    }

    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public int getAge() {
      return age;
    }

    public void setAge(int age) {
      this.age = age;
    }

    @Override
    public String toString() {
      return "Per{" +
          "name='" + name + '\'' +
          ", age=" + age +
          '}';
    }
  }

  public static void main(String[] args) {
    List<Per> list = new ArrayList<>();
    list.add(new Per("listen", 22));
    list.add(new Per("bike", 24));
    list.add(new Per("milk", 27));

    List<String> collect = list.stream().map(Per::toString).collect(Collectors.toList());

    System.out.println(list);
    System.out.println("---");
    System.out.println(collect);

  }

一对一可以实现,那我们该需求,假设一个per人有多个孩子,我们想获取这多个孩子,使用map可以实现吗?比如下面代码。


  static class Child {
    public String name;
    public int age;

    public Child(String name, int age) {
      this.name = name;
      this.age = age;
    }
        @Override
    public String toString() {
      return "Child{" +
          "name='" + name + '\'' +
          ", age=" + age +
          '}';
    }
  }

  static class Per {
    public String name;
    public int age;
    public Child[] Children;

    public Per(String name, int age) {
      this.name = name;
      this.age = age;
    }

    public Child[] getChildren() {
      return Children;
    }

    public void setChildren(Child[] children) {
      Children = children;
    }

    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public int getAge() {
      return age;
    }

    public void setAge(int age) {
      this.age = age;
    }

    @Override
    public String toString() {
      return "Per{" +
          "name='" + name + '\'' +
          ", age=" + age +
          '}';
    }
  }

这个时候注意这个孩子是多个,我们用的是数组存储。如果此时我们还用map,那么只能接受每个per的孩子数组,不能和我们所愿接受每个孩子。


  public static void main(String[] args) {
    List<Per> list = new ArrayList<>();
    Per per1 = new Per("Listen", 22);
    per1.setChildren(new Child[] {new Child("a", 1), new Child("b", 2)});
    Per per2 = new Per("Milk", 26);
    per2.setChildren(new Child[] {new Child("c", 1), new Child("d", 2)});
    list.add(per1);
    list.add(per2);

    List<Child[]> collect = list.stream().map(Per::getChildren).collect(Collectors.toList());
    collect.forEach(item -> System.out.println(Arrays.toString(item)));
  }

而使用flatMap就可以实现。


  public static void main(String[] args) {
    List<Per> list = new ArrayList<>();
    Per per1 = new Per("Listen", 22);
    per1.setChildren(new Child[] {new Child("a", 1), new Child("b", 2)});
    Per per2 = new Per("Milk", 26);
    per2.setChildren(new Child[] {new Child("c", 1), new Child("d", 2)});
    list.add(per1);
    list.add(per2);

    List<Child> collect = list.stream().flatMap(item -> Arrays.stream(item.getChildren())).collect(Collectors.toList());
    System.out.println(collect);

  }

到此这篇关于Java中stream处理中map与flatMap的比较和使用案例的文章就介绍到这了,更多相关Java map与flatMap内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java中stream处理中map与flatMap的比较和使用案例

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录