读书笔记——《Java 8 实战》系列之复合 Lambda 表达式

本贴最后更新于 2822 天前,其中的信息可能已经斗转星移

在上一篇博客中我们一起学习了使用方法引用的方式来重复使用现有的方法并直接传递它们,方法引用能够进一步地简化我们的 Lambda 表达式。在实际问题的处理中,有时候我们需要多个 Lambda 表达式同时进行工作,Java 同样允许我们将多个简单的 Lambda 表达式复合成一个更复杂,完成功能更多的复杂表达式。比如,我们可以将两个谓词做一个 or 的操作,从而组成一个更强大的谓词;或者我们可以让一个函数的结果变成另一个函数的输入(类似于链式处理)。

  • 比较器复合(Comparator 的复合)

1.逆序比较器

  • Comparator reversed() 返回一个逆序后的 Comparator
students.sort(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { // TODO Auto-generated method stub return o1.getAvgScore().compareTo(o2.getAvgScore()); } }.reversed());

2.比较器链

如果使用了上面的比较器后,发现两个学生的平均成绩相同,你可能希望此时按照它们的身高进行排列。此时我们就需要
Comparator thenComparing(Comparator<? super T> other)这个方法来设定当第一个比较器中比较的两个元素相同时该如何进行排序。

students.sort(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { // TODO Auto-generated method stub return o1.getAvgScore().compareTo(o2.getAvgScore()); } }.reversed().thenComparing(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { // TODO Auto-generated method stub return o1.getHeight().compareTo(o2.getHeight()); } }));
  • 谓词复合(Predicate 复合)

谓词的接口中提供了:negate,and 和 or 三个方法,有点类似于我们逻辑运算符中的非,与还有或。比如:

Predicate<Student> highStudents = s -> s.getHeight()>=180;

比如我们想要获得身高小于 180cm 的学生:

Predicate<Student> notHighStudents = highStudents.negate();

我们还可以将两个谓词条件结合起来,比如获得身高大于 180cm,且平均分大于 90 的学生

Predicate<Student> highAndHighScoreStudents = highStudents.and(s -> s.getAvgScore()>90);

我们还可以进一步组合谓词,比如要不然是身高大于 180 且平均分大于 90 分,要不然是平均分小于 60 的学生

Predicate<Student> complicatedPredicate = highStudents.and(s -> s.getAvgScore()>90).or(s -> s.getAvgScore()<60);

这种复合的表达式满足了我们更多的需求,但是读起来确仍然和问题的陈述差不多。需要注意的是,and 和 or 方法是按照在表达式链中的位置,从左向右确定优先级的。因此 a.or(b).and(c)也可以看作是 (a||b) && c

  • 函数复合

我们同样可以把 Function 接口所代表的 Lambda 表达式复合起来。Function 接口提供了两个 andThen 和 compose 两个默认方法,它们都会返回 Function 的一个实例。

andThen 方法会返回一个函数,它会将输入应用给调用这个方法的函数,再将结果应用给这个方法的参数函数。听起来有一些抽象,我们一起来看一个例子:

Function<Integer,Integer> f = x ->x + 1; Function<Integer,Integer> g = x ->x * 2; //先将参数x传入给调用andThen方法的f函数,再将f函数的结果传给andThen方法的参数g函数,得到返回值 Function<Integer,Integer> h = f.andThen(g); //结果返回是4 System.out.println(h.apply(1));

相似的 compose 方法,执行顺序与 andThen 相反,它会先将输入应用给方法参数的函数,再将结果应用给调用这个方法的函数,还是上面的那个例子:

Function<Integer,Integer> f = x ->x + 1; Function<Integer,Integer> g = x ->x * 2; //先将参数x传入给compose方法的参数g函数,再将g函数的结果传给调用compose方法的f函数,得到返回值 Function<Integer,Integer> h = f.compose(g); //结果返回是3 System.out.println(h.apply(1));

下图说明了这两个方法的区别
005f2f238e8e4f6e811d92ff5dca46df-andThen.png

各位同学,到这里,博主就已经用五篇博客将行为参数化Lambda 表达式(一)Lambda 表达式(二)方法引用,复合 Lambda 表达式这几个重要的概念介绍了一遍。如果大家觉得哪里写的有问题,欢迎大家与我一起讨论。

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1062 引用 • 3455 回帖 • 154 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3203 引用 • 8217 回帖 • 2 关注
  • Lambda
    24 引用 • 19 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Office

    Office 现已更名为 Microsoft 365. Microsoft 365 将高级 Office 应用(如 Word、Excel 和 PowerPoint)与 1 TB 的 OneDrive 云存储空间、高级安全性等结合在一起,可帮助你在任何设备上完成操作。

    5 引用 • 34 回帖
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    8 引用 • 26 回帖 • 1 关注
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    61 引用 • 29 回帖 • 10 关注
  • 导航

    各种网址链接、内容导航。

    45 引用 • 177 回帖
  • 笔记

    好记性不如烂笔头。

    311 引用 • 794 回帖
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    948 引用 • 1460 回帖 • 1 关注
  • SQLite

    SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是全世界使用最为广泛的数据库引擎。

    4 引用 • 7 回帖
  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    376 引用 • 1861 回帖
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 2 关注
  • App

    App(应用程序,Application 的缩写)一般指手机软件。

    91 引用 • 384 回帖
  • AngularJS

    AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等。2.0 版本后已经改名为 Angular。

    12 引用 • 50 回帖 • 517 关注
  • WebComponents

    Web Components 是 W3C 定义的标准,它给了前端开发者扩展浏览器标签的能力,可以方便地定制可复用组件,更好的进行模块化开发,解放了前端开发者的生产力。

    1 引用 • 15 关注
  • Follow
    4 引用 • 12 回帖 • 7 关注
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    56 引用 • 85 回帖 • 2 关注
  • frp

    frp 是一个可用于内网穿透的高性能的反向代理应用,支持 TCP、UDP、 HTTP 和 HTTPS 协议。

    17 引用 • 7 回帖 • 3 关注
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 88 关注
  • webpack

    webpack 是一个用于前端开发的模块加载器和打包工具,它能把各种资源,例如 JS、CSS(less/sass)、图片等都作为模块来使用和处理。

    42 引用 • 130 回帖 • 253 关注
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    35 引用 • 468 回帖 • 762 关注
  • JetBrains

    JetBrains 是一家捷克的软件开发公司,该公司位于捷克的布拉格,并在俄国的圣彼得堡及美国麻州波士顿都设有办公室,该公司最为人所熟知的产品是 Java 编程语言开发撰写时所用的集成开发环境:IntelliJ IDEA

    18 引用 • 54 回帖 • 1 关注
  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

    1 引用 • 1 回帖 • 2 关注
  • H2

    H2 是一个开源的嵌入式数据库引擎,采用 Java 语言编写,不受平台的限制,同时 H2 提供了一个十分方便的 web 控制台用于操作和管理数据库内容。H2 还提供兼容模式,可以兼容一些主流的数据库,因此采用 H2 作为开发期的数据库非常方便。

    11 引用 • 54 回帖 • 672 关注
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 617 关注
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    284 引用 • 248 回帖
  • OnlyOffice
    4 引用 • 20 关注
  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    25 引用 • 254 回帖 • 1 关注