User-Profile-Image
hankin
  • 5
  • Java
  • Kotlin
  • Spring
  • Web
  • SQL
  • MegaData
  • More
  • Experience
  • Enamiĝu al vi
  • 分类
    • Zuul
    • Zookeeper
    • XML
    • WebSocket
    • Web Notes
    • Web
    • Vue
    • Thymeleaf
    • SQL Server
    • SQL Notes
    • SQL
    • SpringSecurity
    • SpringMVC
    • SpringJPA
    • SpringCloud
    • SpringBoot
    • Spring Notes
    • Spring
    • Servlet
    • Ribbon
    • Redis
    • RabbitMQ
    • Python
    • PostgreSQL
    • OAuth2
    • NOSQL
    • Netty
    • MySQL
    • MyBatis
    • More
    • MinIO
    • MegaData
    • Maven
    • LoadBalancer
    • Kotlin Notes
    • Kotlin
    • Kafka
    • jQuery
    • JavaScript
    • Java Notes
    • Java
    • Hystrix
    • Git
    • Gateway
    • Freemarker
    • Feign
    • Eureka
    • ElasticSearch
    • Docker
    • Consul
    • Ajax
    • ActiveMQ
  • 页面
    • 归档
    • 摘要
    • 杂图
    • 问题随笔
  • 友链
    • Spring Cloud Alibaba
    • Spring Cloud Alibaba - 指南
    • Spring Cloud
    • Nacos
    • Docker
    • ElasticSearch
    • Kotlin中文版
    • Kotlin易百
    • KotlinWeb3
    • KotlinNhooo
    • 前端开源搜索
    • Ktorm ORM
    • Ktorm-KSP
    • Ebean ORM
    • Maven
    • 江南一点雨
    • 江南国际站
    • 设计模式
    • 熊猫大佬
    • java学习
    • kotlin函数查询
    • Istio 服务网格
    • istio
    • Ktor 异步 Web 框架
    • PostGis
    • kuangstudy
    • 源码地图
    • it教程吧
    • Arthas-JVM调优
    • Electron
    • bugstack虫洞栈
    • github大佬宝典
    • Sa-Token
    • 前端技术胖
    • bennyhuo-Kt大佬
    • Rickiyang博客
    • 李大辉大佬博客
    • KOIN
    • SQLDelight
    • Exposed-Kt-ORM
    • Javalin—Web 框架
    • http4k—HTTP包
    • 爱威尔大佬
    • 小土豆
    • 小胖哥安全框架
    • 负雪明烛刷题
    • Kotlin-FP-Arrow
    • Lua参考手册
    • 美团文章
    • Java 全栈知识体系
    • 尼恩架构师学习
    • 现代 JavaScript 教程
    • GO相关文档
    • Go学习导航
    • GoCN社区
    • GO极客兔兔-案例
    • 讯飞星火GPT
    • Hollis博客
    • PostgreSQL德哥
    • 优质博客推荐
    • 半兽人大佬
    • 系列教程
    • PostgreSQL文章
    • 云原生资料库
    • 并发博客大佬
Help?

Please contact us on our email for need any support

Support
    首页   ›   Java   ›   Java Notes   ›   正文
Java Notes

Lambda最通俗易懂的一篇文章(Java 8)

2020-04-03 15:39:56
1285  0 0

阅读完需:约 7 分钟

什么是Lambda?

“Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)

我们知道,对一个java变量赋值

但是如果你想把一个代码块赋给一个Java变量,怎么做到呢?

比如,把右边的那块代码,赋给左边的叫做aBlockOfCode的变量:

这在Java 8之前是做不到的。Java 8问世之后,利用Lambda特性就可以做到了。

当然这还不算最简洁的写法,为了使代码更简练,我们可以做以下操作,移除没用的声明

这样,我们成功优雅地把一个代码块赋给了一个变量。而这个代码块,或者说这个被赋给一个变量的函数,就是一个Lambda表达式。

但这里仍然存在一个问题,那就是变量aBlockOfCode的类型应该是什么?

在Java 8里面,所有的Lambda的类型都是一个接口,而Lambda表达式本身,也就是那个代码块,需要是这个接口的实现。这是我认为理解Lambda的一个关键点所在,简言之,Lambda表达式本身就是一个接口的实现。这样说可能还是有些困惑,继续举例。

我们给aBlockOfCode加上一个类型:

这种只有一个接口函数需要被实现的接口类型,我们叫它”函数式接口”。为了避免后来的人在这个接口中增加接口函数导致其有多个接口函数需要被实现,变成”非函数接口”,我们可以加上一个声明@FunctionalInterface, 这样别人就没有办法在里面添加新的接口函数了:

这样,我们就得到了一个完整的Lambda表达式声明:

Lambda表达式有什么作用?

最直观的作用就是使得代码变得非常简洁。

我们可以对比一下Lambda表达式和传统的Java对同一个接口的实现:

这两种写法本质上是一样的。但是很明显,Java 8中的写法更加优雅简洁。并且,由于Lambda可以直接赋值给一个变量,我们就可以直接把Lambda作为参数传给函数, 而传统的Java必须有明确的接口实现的定义,初始化才可以:

有些情况下,这个接口实现只需要用到一次。传统的Java 7要求你必须定义一个“污染环境”的接口实现MyInterfaceImpl,相对而言Java 8的Lambda, 就显得干净很多。

————————————————————————

Lambda结合FunctionalInterface Lib, forEach, stream(),method reference等新特性可以使代码变的更加简洁!

举例说明:

假设Person的定义和List<Person>的值都给定。

现在需要你打印出guiltyPersons List里面所有LastName以”Z”开头的人的FirstName。

原生态Lambda写法:定义两个函数式接口,定义一个静态函数,调用静态函数并给参数赋值Lambda表达式。

这个代码实际上已经比较简洁了,但是我们还可以更简洁么?

当然可以。在Java 8中有一个函数式接口的包,里面定义了大量可能用到的函数式接口(java.util.function (Java Platform SE 8 ))。所以,我们在这里压根都不需要定义NameChecker和Executor这两个函数式接口,直接用Java 8函数式接口包里的Predicate<T>和Consumer<T>就可以了——因为他们这一对的接口定义和NameChecker/Executor其实是一样的。

第一步简化 – 利用函数式接口包:

静态函数里面的for each循环其实是非常碍眼的。这里可以利用Iterable自带的forEach()来替代。forEach()本身可以接受一个Consumer<T> 参数。

第二步简化 – 用Iterable.forEach()取代foreach loop:

由于静态函数其实只是对List进行了一通操作,这里我们可以甩掉静态函数,直接使用stream()特性来完成。stream()的几个方法都是接受Predicate<T>,Consumer<T>等参数的(java.util.stream (Java Platform SE 8 ))。你理解了上面的内容,stream()这里就非常好理解了,并不需要多做解释。

第三步简化 – 利用stream()替代静态函数:

对比最开始的Lambda写法,这里已经非常非常简洁了。但是如果,我们的要求变一下,变成print这个人的全部信息,即p -> System.out.println(p); 那么还可以利用Method reference来继续简化。所谓Method reference, 就是用已经写好的别的Object/Class的method来代替Lambda expression。格式如下:

第四步简化 – 如果是println(p),则可以利用Method reference代替forEach中的Lambda表达式:

这基本上就是能写的最简洁的版本了。

————————————————————————

Lambda配合Optional<T>可以使Java对于null的处理变的异常优雅

这里假设我们有一个person object,以及一个person object的Optional wrapper:

Optional<T>如果不结合Lambda使用的话,并不能使原来繁琐的null check变的简单。

只有当Optional<T>结合Lambda一起使用的时候,才能发挥出其真正的威力!

我们现在就来对比一下下面四种常见的null处理中,Java 8的Lambda+Optional<T>和传统Java两者之间对于null的处理差异。

情况一 – 存在则开干

情况二 – 存在则返回,无则返回屁

情况三 – 存在则返回,无则由函数产生

情况四 – 夺命连环null检查

由上述四种情况可以清楚地看到,Optional<T>+Lambda可以让我们少写很多ifElse块。尤其是对于情况四那种夺命连环null检查,传统java的写法显得冗长难懂,而新的Optional<T>+Lambda则清新脱俗,清楚简洁。

更多示例:

https://www.cnblogs.com/coprince/p/8692972.html

如本文“对您有用”,欢迎随意打赏作者,让我们坚持创作!

0 打赏
Enamiĝu al vi
不要为明天忧虑.因为明天自有明天的忧虑.一天的难处一天当就够了。
543文章 68评论 294点赞 594134浏览

随机文章
Java—POI操作Excel
5年前
Kotlin-注解—注解(三十)
4年前
Java—类加载内存
5年前
Java—并发编程(七)JUC集合 – (4) ConcurrentHashMap
4年前
Spring Security—登录添加验证码
5年前
博客统计
  • 日志总数:543 篇
  • 评论数目:68 条
  • 建站日期:2020-03-06
  • 运行天数:1927 天
  • 标签总数:23 个
  • 最后更新:2024-12-20
Copyright © 2025 网站备案号: 浙ICP备20017730号 身体没有灵魂是死的,信心没有行为也是死的。
主页
页面
  • 归档
  • 摘要
  • 杂图
  • 问题随笔
博主
Enamiĝu al vi
Enamiĝu al vi 管理员
To be, or not to be
543 文章 68 评论 594134 浏览
测试
测试
看板娘
赞赏作者

请通过微信、支付宝 APP 扫一扫

感谢您对作者的支持!

 支付宝 微信支付