一对多的提取内容用flatmap,一对一用map

java 8 stream api 中有两个方法map和flatMap非常实用,应用场景也非常广泛,能极大提升编程效率。下面我们详细介绍一下这两个方法的用法。

map方法

我们来看个示例:把一个整数列表转换成字符串列表,java 8之前常用的实现方法如下

ListnumList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);

ListstrList = new ArrayList<>();

for (int num : numList) {

strList.add(Integer.toString(num));

}

这种写法比较符合直觉,但略显繁琐。如果用java 8的stream api的map方法则可以把这个过程变的非常简洁

ListstrList = numList.stream()

.map(it -> Integer.toString(it))

.collect(Collectors.toList());

map方法接受一个lambda表达式,这个表达式是一个函数,输入类型是集合元素的类型,输出类型是任意类型

it -> Integer.toString(it)

在示例中就是将集合中的整数元素逐个转换成字符串类型。这种写法和常规的编程思路不同,却有点像SQL

select id from table1

这条SQL语句读取一张表的id字段,id是int类型,我们将他转换成字符类型,实现方法如下

select cast(id as CHAR(10)) as id from table1

SQL中的select对应的是map方法

cast(id as CHAR(10)) 对应的就是 it -> Integer.toString(it)

我们还可以用map实现很多效果,比如转换成符合要求的bool列表

ListboolList = numList.stream()

.map(it -> it > 5 ? true : false)

.collect(Collectors.toList());

或者转换成某种对象列表

public class Main {

private static class Klass {

private int field;

public Klass(int field) {

this.field = field;

}

@Override

public String toString() {

return "field=" + field;

}

}

public static void main(String[] args) {

ListnumList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);

ListobjList = numList.stream()

.map(it -> new Klass(it))

.collect(Collectors.toList());

}

}

都可以非常迅速的实现,和那些流水账式的代码告别

ListobjList2 = new ArrayList<>();

for (int num : numList) {

objList2.add(new Klass(num));

}

其实这种写法就是函数式编程的声明性编程,将代码写成表达式类型。而我们常用的SQL语言天生就是函数式语言。

flatMap方法

我们把需求扩展下

先定义两个类型

private static class Klass {

private int field;

public Klass(int field) {

this.field = field;

}

@Override

public String toString() {

return "field=" + field;

}

}

private static class KlassGroup {

private Listgroup = new ArrayList<>();

public KlassGroup(Klass... objList) {

for (Klass item : objList) {

this.group.add(item);

}

}

public ListgetKlassList() {

return group;

}

}

KlassGroup类中定义了一个Klass类的列表

现在我们有一组KlassGroup对象

ListgroupList = Arrays.asList(

new KlassGroup(new Klass(1), new Klass(2), new Klass(3)),

new KlassGroup(new Klass(4), new Klass(5), new Klass(6)),

new KlassGroup(new Klass(7), new Klass(8), new Klass(9)),

new KlassGroup(new Klass(10))

);

需要将每个KlassGroup对象中的那些Klass类取出来,放到一个ArrayList里面,得到一个List。我们尝试着用map方法来实现

List> result = groupList.stream()

.map(it -> it.getKlassList())

.collect(Collectors.toList());

哈,不成功,我们想要的结果是List,现在得到了 List>。当然,我们可以轻而易举的解决这个问题

Listresult2 = new ArrayList<>();

for (KlassGroup group : groupList) {

for (Klass klass : group.getKlassList()) {

result2.add(klass);

}

}

但是这种套了两层for循环的代码太丑陋了。面对这种需求,flatMap可以大展身手了

Listresult3 = groupList.stream()

.flatMap(it -> it.getKlassList().stream())

.collect(Collectors.toList());

一行代码就实现了

stream api 的 flatMap方法接受一个lambda表达式函数, 函数的返回值必须也是一个stream类型,flatMap方法最终会把所有返回的stream合并,map方法做不到这一点,如果用map去实现,会变成这样一个东西

List> result3 = groupList.stream()

.map(it -> it.getKlassList().stream())

.collect(Collectors.toList());

flatMap的思路在其他语言中也有体现,比如C# Linq中的 SelectMany 方法,F# 中的 List.collect方法都有同样的作用。用函数式编程的说法,他们都实现了 monad,当然,monad这个概念很难是通俗的描述清楚,此文中就不展开了。

java 8 stream api 中各方法可以极大的简化集合操作,带来大幅度的编码效率提升,如果是java 8及以上的版本,一定要优先使用,stream api绝对是java中史诗级的工作效率提升利器。

java steam说明_Java 8 Steam API map和flatMap方法使用详解相关推荐

  1. java flatmap_Java 8 Steam API map和flatMap方法使用详解

    java 8 stream api 中有两个方法map和flatMap非常实用,应用场景也非常广泛,能极大提升编程效率.下面我们详细介绍一下这两个方法的用法. map方法 我们来看个示例:把一个整数列 ...

  2. Java 8 Steam API map和flatMap方法使用详解

    java 8 stream api 中有两个方法map和flatMap非常实用,应用场景也非常广泛,能极大提升编程效率.下面我们详细介绍一下这两个方法的用法. map方法 我们来看个示例:把一个整数列 ...

  3. java condition详解_Java使用Condition控制线程通信的方法实例详解

    Java使用Condition控制线程通信的方法实例详解 发布于 2020-4-20| 复制链接 摘记: 本文实例讲述了Java使用Condition控制线程通信的方法.分享给大家供大家参考,具体如下 ...

  4. java 值对象_java 中设计模式(值对象)的实例详解

    java 中设计模式(值对象)的实例详解 应用场景:在Java开发时,需要来回交换大量的数据,比如要为方法传入参数,也要获取方法的返回值,该如何能更好的进行数据的交互?这个时候就需要用到我们的值对象设 ...

  5. java判断或_Java判断用户名和密码是否符合要求过程详解

    这篇文章主要介绍了Java判断用户名和密码过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 假设在某仓库管理系统的登录界面中需要输入用户名和密 ...

  6. java metadata 使用_java 查询oracle数据库所有表DatabaseMetaData的用法(详解)

    一 . 得到这个对象的实例 Connection con ; con = DriverManager.getConnection(url,userName,password); DatabaseMet ...

  7. java正则 环视_Java正则环视和反向引用功能与用法详解

    本文实例讲述了Java正则环视和反向引用功能与用法.分享给大家供大家参考,具体如下: 环视 1.环视概念 环视,又称为零宽断言,简称断言. 环视强调位置(前面或后面),必须匹配环视表达式,才能匹配成功 ...

  8. java手机模式_Java使用建造者模式实现办理手机套餐功能详解

    本文实例讲述了Java使用建造者模式实现办理手机套餐功能.分享给大家供大家参考,具体如下: 一.模式定义 建造者简单理解就是造东西,只不过建造者模式建造的不是一个简单的东西,是一个比较复杂的东西. 二 ...

  9. java手势识别技术_Java乔晓松-android中的手势识别的详解

    对于android中的手势识别,效果如下图所示: 模拟器中有个可以添加手势的工具Gestures Builder,可以添加手势如下图所示: 当添加手势成功后,会在Sdcard上产生保存的手势的文件ge ...

最新文章

  1. python做ui自动化_[python]RobotFramework自定义库实现UI自动化
  2. 后缀数组的学习(三):SA数组实现代码分析
  3. 【工作总结】C++ string工具类
  4. 笔记本安装linux系统_Win10怎么安装linux双系统?win10安装linux双系统教程
  5. Redis安装-win-linux-mac
  6. jboss默认进程名称_快速指南:剖析JBoss BPM跨进程通信
  7. 无显示器u盘安装centos_最新版 CentOS 8.1.1911 安装教程及常见问题图文详解
  8. java常用的统计_(OJ)Java常用类-统计数字次数
  9. daisy_DAISY:视障人士的Linux兼容文本格式
  10. 【codevs1565】【BZOJ2242】计算器,数论练习
  11. MongoDB SQL
  12. WCF简单教程(2) 聊聊binding
  13. 对物联网的感悟_物联网学习心得
  14. 【商业】梳理你的商业模式
  15. 树莓派cm4安装ax200驱动-wifi6
  16. 数字转换为中文大写(钱数)
  17. date日期格式 yyyy-MM-dd HH:mm:ss 大小写区别
  18. 华为+android+root权限获取root,[Android]如何获取华为手机的root权限
  19. 【Python蓝桥杯】印章 共有n种图案的印章,每种图案的出现概率相同。小A买了m张印章,求小A集齐n种印章的概率。
  20. 基于改进yolov4和unet的飞机目标的分割

热门文章

  1. 百姓网上怎么引流?百姓网如何发帖引流?百姓网如何推广?
  2. Java经典问题算法大全 Java小程序
  3. 【计算机毕业设计】心理健康教育系统
  4. BTM主题模型构建及困惑度计算
  5. vivado 综合与实现
  6. Xmind 8 快捷键
  7. 例题:索洛模型——要素支付
  8. Spring请求参数和响应结果全局加密和解密(1)
  9. windows系统的安装时间怎么查看
  10. TimerTask()定时器使用详解