1.函数定义比较

map注释:

/**

* Returns a stream consisting of the results of applying the given

* function to the elements of this stream.

*

*

This is an intermediate

* operation.

*

* @param The element type of the new stream

* @param mapper a non-interfering,

* stateless

* function to apply to each element

* @return the new stream

*/

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

翻译过来:

返回由将给定函数应用于该流元素的结果组成的流。

这是一个中间操作。

参数:

映射器-适用于每个元素的无干扰、无状态功能

类型参数:

新流的元素类型

返参:新流

也就是说你的集合中的元素是什么类型就返回该元素的流。

flatMap注释:

/**

* Returns a stream consisting of the results of replacing each element of

* this stream with the contents of a mapped stream produced by applying

* the provided mapping function to each element. Each mapped stream is

* {@link java.util.stream.BaseStream#close() closed} after its contents

* have been placed into this stream. (If a mapped stream is {@code null}

* an empty stream is used, instead.)

*

*

This is an intermediate

* operation.

*

* @apiNote

* The {@code flatMap()} operation has the effect of applying a one-to-many

* transformation to the elements of the stream, and then flattening the

* resulting elements into a new stream.

*

*

Examples.

*

*

If {@code orders} is a stream of purchase orders, and each purchase

* order contains a collection of line items, then the following produces a

* stream containing all the line items in all the orders:

*

{@code

* orders.flatMap(order -> order.getLineItems().stream())...

* }

*

*

If {@code path} is the path to a file, then the following produces a

* stream of the {@code words} contained in that file:

*

{@code

* Stream lines = Files.lines(path, StandardCharsets.UTF_8);

* Stream words = lines.flatMap(line -> Stream.of(line.split(" +")));

* }

* The {@code mapper} function passed to {@code flatMap} splits a line,

* using a simple regular expression, into an array of words, and then

* creates a stream of words from that array.

*

* @param The element type of the new stream

* @param mapper a non-interfering,

* stateless

* function to apply to each element which produces a stream

* of new values

* @return the new stream

*/

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

翻译过来:

返回由将该流的每个元素替换为通过将所提供的映射功能应用到每个元素而产生的映射流的内容的结果组成的流。每个映射的流在其内容已被放置到该流中之后被关闭。(如果映射的流是空的,则使用空的流。)

这是一个中间操作。

参数:

映射器-无干扰、无状态功能,适用于产生新数值流的每个元素

类型参数:

新流的元素类型

返参:

新流

Apinote:

FlatMap()操作具有对该流的元素应用一对多变换的效果,然后将所得到的元素展平到新的流中。

案例.

如果订单是采购订单的流,并且每个采购订单包含一系列行项目,则以下将生成包含所有订单中所有行项目的流:

orders.flatMap(order -> order.getLineItems().stream())...

如果路径是到文件的路径,则以下会产生包含在该文件中的单词的流:

Stream lines = Files.lines(path, StandardCharsets.UTF_8);

Stream words = lines.flatMap(line -> Stream.of(line.split(" +")));

传递到FlatMap的映射器函数使用简单正则表达式将一行分割为单词数组,然后从该数组创建一个单词流

我的理解是假如你的集合流中包含子集合,那么使用flatMap可以返回该子集合的集合流.

2.案例比较

假如我们有地址类,一个地址类包含多个城市将地址类作为集合,我们想输出所有的城市的名字。

数据结构:

1.jpg

地址类:

//地址类

public class Address {

private String province;

private List cityList;//市集合

public String getProvince() {

return province;

}

public void setProvince(String province) {

this.province = province;

}

public List getCityList() {

return cityList;

}

public void setCityList(List cityList) {

this.cityList = cityList;

}

@Override

public String toString() {

return "Address{" +

"province='" + province + '\'' +

", cityList=" + cityList +

'}';

}

}

测试案例

public static void main(String[] args) {

List cityListOne = new ArrayList<>();

cityListOne.add("郑州");

cityListOne.add("濮阳");

List cityListTwo = new ArrayList<>();

cityListTwo.add("廊坊");

cityListTwo.add("邢台");

List cityListThree = new ArrayList<>();

cityListThree.add("大同");

cityListThree.add("太原");

List cityListFour = new ArrayList<>();

cityListFour.add("南昌");

cityListFour.add("九江");

Address addressOne = new Address();

addressOne.setProvince("河南");

addressOne.setCityList(cityListOne);

Address addressTwo = new Address();

addressTwo.setProvince("河北");

addressTwo.setCityList(cityListTwo);

Address addressThree = new Address();

addressThree.setProvince("山西");

addressThree.setCityList(cityListThree);

Address addressFour = new Address();

addressFour.setProvince("江西");

addressFour.setCityList(cityListFour);

List

addresseList = new ArrayList<>();

addresseList.add(addressOne);

addresseList.add(addressTwo);

addresseList.add(addressThree);

addresseList.add(addressFour);

//使用map输出所有的城市名称

addresseList.stream()

.map(a -> a.getCityList())

.forEach(cityList->{ cityList.forEach(city -> System.out.print(city));

});

System.out.println("");

//使用flatMap输出所有城市名称

addresseList.stream()

.flatMap(a -> a.getCityList().stream())

.forEach(city -> System.out.print(city));

}

输出结果

郑州濮阳廊坊邢台大同太原南昌九江

郑州濮阳廊坊邢台大同太原南昌九江

可以看出两个循环结果一致,但是map处理方式是在foreach中将cityList作为集合再次循环,而flatMap可以直接将cityList中的城市直接进行循环输出。也就是说flatMap可以获取集合中的集合的流在外层可以直接处理

3.map强行获取流会如何?

如果我们使用map强行获取流进行循环会如何呢?

//使用map输出所有的城市名称

addresseList.stream()

.map(a -> a.getCityList())

.forEach(cityList->{ cityList.forEach(city -> System.out.print(city));

});

//使用map强行获取流进行输出,写法和flatMap一致

addresseList.stream()

.map(a -> a.getCityList().stream())

.forEach(city->System.out.println(city));

//使用flatMap输出所有城市名称

addresseList.stream()

.flatMap(a -> a.getCityList().stream())

.forEach(city -> System.out.print(city));

打印结果:

郑州濮阳廊坊邢台大同太原南昌九江

java.util.stream.ReferencePipeline$Head@21588809

java.util.stream.ReferencePipeline$Head@2aae9190

java.util.stream.ReferencePipeline$Head@2f333739

java.util.stream.ReferencePipeline$Head@77468bd9

郑州濮阳廊坊邢台大同太原南昌九江

可以看到使用map如果和flatMap写法一样强行获取流进行打印,打印的是流对象的信息,而不是流对象中的集合信息。

4.使用多次flatMap

flatMap也可以使用多次,则会把更深一层的集合流中的数据在外层进行处理

在上面的案例中,我们假如再添加一个用户类 用户类中包含地址类集合

数据结构

2.jpg

用户类

public class User {

private String name;

private List

addressList;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public List

getAddressList() {

return addressList;

}

public void setAddressList(List

addressList) {

this.addressList = addressList;

}

@Override

public String toString() {

return "User{" +

"name='" + name + '\'' +

", addressList=" + addressList +

'}';

}

}

测试案例

public static void main(String[] args) {

List cityListOne = new ArrayList<>();

cityListOne.add("郑州");

cityListOne.add("濮阳");

List cityListTwo = new ArrayList<>();

cityListTwo.add("廊坊");

cityListTwo.add("邢台");

List cityListThree = new ArrayList<>();

cityListThree.add("大同");

cityListThree.add("太原");

List cityListFour = new ArrayList<>();

cityListFour.add("南昌");

cityListFour.add("九江");

Address addressOne = new Address();

addressOne.setProvince("河南");

addressOne.setCityList(cityListOne);

Address addressTwo = new Address();

addressTwo.setProvince("河北");

addressTwo.setCityList(cityListTwo);

Address addressThree = new Address();

addressThree.setProvince("山西");

addressThree.setCityList(cityListThree);

Address addressFour = new Address();

addressFour.setProvince("江西");

addressFour.setCityList(cityListFour);

List

addresseListOne = new ArrayList<>();

addresseListOne.add(addressOne);

addresseListOne.add(addressTwo);

List

addresseListTwo = new ArrayList<>();

addresseListTwo.add(addressThree);

addresseListTwo.add(addressFour);

//新增用户来包含地址集合

List userList = new ArrayList<>();

User u1 = new User();

u1.setName("张三");

u1.setAddressList(addresseListOne);

User u2 = new User();

u2.setName("李四");

u2.setAddressList(addresseListTwo);

userList.add(u1);

userList.add(u2);

//使用map输出所有的城市名称

userList.stream()

.map(u->u.getAddressList())

.forEach(addressList->{

addressList.forEach(address -> {

address.getCityList().forEach(city->{

System.out.print(city);

});

});

});

System.out.println("");//换行

//使用flatMap输出所有城市名称

userList.stream()

.flatMap(u -> u.getAddressList().stream())

.flatMap(a -> a.getCityList().stream())

.forEach(city -> System.out.print(city));

}

打印结果

郑州濮阳廊坊邢台大同太原南昌九江

郑州濮阳廊坊邢台大同太原南昌九江

可以看出flatMap可以使用多次将更深一层的集合流中的数据拿到外层进行处理。而使用map则相当繁琐

以上就是我对java8中map和flatMap的理解

java8 flatmap与map_java8中map和flatMap区别相关推荐

  1. Java8高效遍历map_Java8中Map的遍历方式总结

    在这篇文章中,我将对Map的遍历方式做一个对比和总结,将分别从JAVA8之前和JAVA8做一个遍历方式的对比,亲测可行. public class LambdaMap { private Map ma ...

  2. Java基础之Java8中map和flatMap的使用

    Java基础之Java8中map和flatMap的使用 一.介绍 首先,看下map和flatMap的官方文档说明 map flatMap 其实单纯的看api说明还是比较抽象,下面我将以几个实战例子来帮 ...

  3. stream map方法_Java Stream中map和flatMap方法

    最近看到一篇讲stream语法的文章,学习Java中map()和flatMap()方法之间的区别. 虽然看起来这两种方法都做同样的事情,都是做的映射操作,但实际上差之毫厘谬以千里. 通过演示Demo中 ...

  4. java flatmapfunction_Java Stream中map和flatMap方法

    最近看到一篇讲stream语法的文章,学习Java中map()和flatMap()方法之间的区别. 虽然看起来这两种方法都做同样的事情,都是做的映射操作,但实际上差之毫厘谬以千里. 通过演示Demo中 ...

  5. Java8中map与flatMap用法

    目录 1 概述 2 map与flatMap 3 常用写法 1 概述 Java8中一些新特性在平时工作中经常会用到,但有时候总感觉不是很熟练,今天特意将这个Java8中的映射记录一下. 2 map与fl ...

  6. map写法 scala语言_(转)scala中map与flatMap浅析

    在函数式语言中,函数作为一等公民,可以在任何地方定义,在函数内或函数外,可以作为函数的参数和返回值,可以对函数进行组合.由于命令式编程语言也可以通过类似函数指针的方式来实现高阶函数,函数式的最主要的好 ...

  7. Stream中map和flatmap的区别,一看就懂

    在日常开发中,我们经常会使用Stream来处理集合的操作. 其中,map是我们经常用到的api方法,同时呢,Stream也给我们提供了flatmap的方法. 这时候很多小伙伴就会搞不懂,这map和fl ...

  8. 【收藏】spark中map与mapPartitions区别

    两个函数最终处理得到的结果是一样的 mapPartitions比较适合需要分批处理数据的情况,比如将数据插入某个表,每批数据只需要开启一次数据库连接,大大减少了连接开支,伪代码如下: arrayRDD ...

  9. java8 stream to map_Java 8 Stream Api 中的 map和 flatMap 操作

    1.前言 Java 8 提供了非常好用的 Stream API ,可以很方便的操作集合.今天我们来探讨两个 Stream 中间操作 map 和 flatMap 2. map 操作 map 操作是将流中 ...

最新文章

  1. Ocelot + Consul实践
  2. 分布式服务框架-原理与实践:14---流量控制-学习笔记(理论篇)
  3. 资讯丨谷歌 AutoML AI系统写的机器学习代码,完爆程序员
  4. 怎么安装python3-centos编译安装python3怎么做?
  5. Jrebel最新激活破解方式
  6. 《柯南 绯红色的子弹》 观后感
  7. 图像处理理论(七)——LBP, Fisherface, Viola-Jones
  8. 混合多云架构_使用混合多云每个人都应避免的3个陷阱(第3部分)
  9. python 项目结构图_python+selenium-【六】-完整的项目结构
  10. linux用户limit修改,linux – 使用cgroups作为用户设置用户创建的systemd范围的MemoryLimit...
  11. go get如何删除_Go语言HTTP请求(req库)
  12. 一文读懂C++程序的结构、执行与编译
  13. UAS:大众点评用户行为系统
  14. 一个简单的显示阴历的日历。
  15. 长城皮卡品牌CEO张昊保:皮卡是一个独特的品类,想玩门槛很高
  16. Neutron OVS-DVR
  17. Presto RBO之broadcast join与partitioned join类型的选择优化
  18. 使用基于时间的关系加权标准来改善社交网络中的链接预测
  19. 21Maven - 从私服下载jar包
  20. Java 基础知识面试题(2021最新版)

热门文章

  1. 管理的价值 | 陆奇推崇的洛克菲勒原则 (Rockefeller Habits)与每日站会、回顾会、OKR、价值观、团队...
  2. Machine-Learning-for-Algorithmic-Trading-Second-Edition/ Create_datasets feature_engineering
  3. 网易雷火游戏测试实习一二三四面面经
  4. API 接口获得店铺商品商品详情返回值说明
  5. Math/ML:序列监督学习-时间序列数据集/时间序列预测任务的简介、常用算法及其工具、案例应用之详细攻略
  6. 360推出儿童卫士2,硬件细节再更迭
  7. 个人记录lingo的学习
  8. 下一个 Brython? 不, 是 Python in WebAseembly
  9. draw.io---一款免费、开源的流程图绘制工具
  10. oracle 触发器执行ddl,在Oracle的触发器中执行DDL语句