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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java8 Stream flatmap中间操作用法解析

    stream中的flatmap是stream的一种中间操作,它和stream的map一样,是一种收集类型的stream中间操作,但是与map不同的是,它可以对stream流中单个元素再进行拆分(切片),从另一种角度上说,使用了它,就是使用了双重for循环. 查看Stream源码中flatmap的方法定义: <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapp

  • 关于Java8中map()和flatMap()的一些事

    两个方法的背景 这两个方法看起来做着同样的事情,但实际上又有些不一样.看源码部分是这样的 package java.util.stream; map()方法 /** * @param <R> The element type of the new stream * @param mapper a <a href="package-summary.html#NonInterference" rel="external nofollow" rel=&q

  • Java 8 Stream Api 中的 map和 flatMap 操作方法

    1.前言 Java 8提供了非常好用的 Stream API ,可以很方便的操作集合.今天我们来探讨两个 Stream中间操作 map(Function<? super T, ? extends R> mapper) 和 flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) 2. map 操作 map 操作是将流中的元素进行再次加工形成一个新流.这在开发中很有用.比如我们有一个学生集合,我们

  • 浅谈java8 stream flatMap流的扁平化操作

    概念: Steam 是Java8 提出的一个新概念,不是输入输出的 Stream 流,而是一种用函数式编程方式在集合类上进行复杂操作的工具.简而言之,是以内部迭代的方式处理集合数据的操作,内部迭代可以将更多的控制权交给集合类.Stream 和 Iterator 的功能类似,只是 Iterator 是以外部迭代的形式处理集合数据的操作. 在Java8以前,对集合的操作需要写出处理的过程,如在集合中筛选出满足条件的数据,需要一 一遍历集合中的每个元素,再把每个元素逐一判断是否满足条件,最后将满足条件

  • Java8如何基于flatMap处理异常函数

    Java8的flatMap函数,作用是:如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional. 见到的映射函数往往都只有一句话,连大括号都不需要加的,如下: String personValue = Optional.ofNullable(map.get("person")) .flatMap(value -> Optional.of(value.toString().trim())) .orElse(""); 可是如

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

    前言 使用Java8的新特性Stream流式处理,可以提高对于集合的一些操作效率,再配合lambda表达式,可以极致的简化代码,尤其还有并行流这个东东,可以去 了解一下,在一些场合还是可以提高效率的,而且编码起来也不费事. 并且流式处理的核心就是一个浅拷贝和引用管道,其内部实现了一个引用管道ReferencePipeline, 他把需要处理的数据的引用拷贝了一份,然后处理数据,最后收集结果也是将这些引用放到了另一个集合中. 今天要讲的就是stream处理中的map和flatMap这俩个的比较和使

  • Java中Stream流中map和forEach的区别详解

    目录 什么是 stream 流 Map forEach 使用场景 不是很难的知识,但是今天犯错了,记录一下 什么是 stream 流 我们在使用集合或数组对元素进行操作时往往会遇到这种情况:通过对不同类型的存储元素,按照特定条件进行查找.排序.等操作时往往会写一大段代码,而且更要命的是,不同类型的数据,操作的方法也不一样,比如一个存储 Student 实体类和一个只存储 String 类型的集合俩者的操作步骤肯定大不一样且无法通用,而 stream API 就解决了这些问题,对数据操作时进行了统

  • Java中stream.map和stream.forEach的区别

    目录 什么是 stream 流 stream.map 和 stream.forEach 的区别 网上很多关于讲解这俩个区别的文章,但大多数要么不明不白,要么太复杂难理解.所以自己通俗的讲一下,毕竟不会太深奥,只是个人理解 (评论区指出了错误改了一下). 什么是 stream 流 我们在使用集合或数组对元素进行操作时往往会遇到这种情况:通过对不同类型的存储元素,按照特定条件进行查找.排序.等操作时往往会写一大段代码,而且更要命的是,不同类型的数据,操作的方法也不一样,比如一个存储 Student

  • 一文详解Java中Stream流的使用

    目录 简介 操作1:创建流 操作2:中间操作 筛选(过滤).去重 映射 排序 消费 操作3:终止操作 匹配.最值.个数 收集 规约 简介 说明 本文用实例介绍stream的使用. JDK8新增了Stream(流操作) 处理集合的数据,可执行查找.过滤和映射数据等操作. 使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询.可以使用 Stream API 来并行执行操作. 简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式. 特点 不是数据结构

  • java基础理论Stream管道流Map操作示例

    目录 一.回顾Stream管道流map的基础用法 二.处理非字符串类型集合元素 三.再复杂一点:处理对象数据格式转换 四.flatMap 一.回顾Stream管道流map的基础用法 最简单的需求:将集合中的每一个字符串,全部转换成大写! List<String> alpha = Arrays.asList("Monkey", "Lion", "Giraffe", "Lemur"); //不使用Stream管道流 L

  • 关于JAVA中stream流的基础处理(获取对象字段和对象批量处理等)

    目录 Stream流程处理情况 1:按指定字段获取集合对象中的字段: 2:按指定字段对集合对象进行排序: 3: 按指定字段对集合对象去重处理 4: 对集合对象批量处理 5: 将集合对象中指定字段转数组 Stream流程处理情况 1:按指定字段获取集合对象中的字段: List<String> idList = initUserList.stream().map(User::getId).collect(Collectors.toList()); 2:按指定字段对集合对象进行排序: List<

  • Java中List Set和Map之间的区别_动力节点Java学院整理

    Java集合的主要分为三种类型: • Set(集) • List(列表) • Map(映射) 要深入理解集合首先要了解下我们熟悉的数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),而JAVA集合可以存储和操作数目不固定的一组数据. 所有的JAVA集合都位于 java.util包中! JAVA集合只能存放引用类型的的数据,不能存放基本数据类型. 世间上本来没有集合,(只有数组参考C语言)但有人想要,所以有了集合 有人想有可以自动扩展的数组,所以有了List 有的

  • 多用多学之Java中的Set,List,Map详解

    很长时间以来一直代码中用的比较多的数据列表主要是List,而且都是ArrayList,感觉有这个玩意就够了.ArrayList是用于实现动态数组的包装工具类,这样写代码的时候就可以拉进拉出,迭代遍历,蛮方便的. 也不知道从什么时候开始慢慢的代码中就经常会出现HashMap和HashSet之类的工具类.应该说HashMap比较多一些,而且还是面试经典题,平时也会多看看.开始用的时候简单理解就是个键值对应表,使用键来找数据比较方便.随后深入了解后发现 这玩意还有点小奥秘,特别是新版本的JDK对Has

  • JAVA中JSONObject对象和Map对象之间的相互转换

    1.由json字符串转换成Map对象 如json字符串:{"contend":[{"bid":"22","carid":"0"},{"bid":"22","carid":"0"}],"result":100,"total":2} 下面直接附代码: //json字符串 String json

  • Java中List  Set和Map之间的区别_动力节点Java学院整理

    Java集合的主要分为三种类型: • Set(集) • List(列表) • Map(映射) 要深入理解集合首先要了解下我们熟悉的数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),而JAVA集合可以存储和操作数目不固定的一组数据. 所有的JAVA集合都位于 java.util包中! JAVA集合只能存放引用类型的的数据,不能存放基本数据类型. 世间上本来没有集合,(只有数组参考C语言)但有人想要,所以有了集合 有人想有可以自动扩展的数组,所以有了List 有的

随机推荐