Java8函数式编程以及Lambda表达式
第一章 认识Java8以及函数式编程
关注公众号(CoderBuff)回复“stream”获取《Java8 Stream编码实战》PDF完整版。
《Java8 Stream编码实战》的代码全部在https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/stream-coding,一定要配合源码阅读,并且不断加以实践,才能更好的掌握Stream。
尽管距离Java8发布已经过去7、8年的时间,但时至今日仍然有许多公司、项目停留在Java7甚至更早的版本。即使已经开始使用Java8的项目,大多数程序员也仍然采用“传统”的编码方式。
即使是在Java7就已经有了处理异常的新方式——try-with-resources
,但大多数程序员也仍然采用在finally
语句中关闭相应的资源。
我认为Java8和Java5的意义同等重要,Java5的众多新特性使得Java正式迈入编程界的统治地位。同样,Java8的发布,也使得这一门“古老”的语言具备了更加现代化的特性。
Java8最为引入瞩目就是支持函数式编程。
如果说面向对象编程是对数据的抽象,那么函数式编程就是对行为的抽象[1]。
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.out.println("button clicked");
}
});
这个示例是为了一个按钮增加一个监听,当点击这个按钮时,将会触发打印“button clicked”行为。
在Java支持函数式编程以前,我们如果需要传递一个行为常用的方式就是传递一个对象,而匿名内部类正是为了方便将代码作为数据进行传递。
当然,函数式编程,并不是在Java8中才提出来的新概念,
函数式编程属于编程范式中的一种,它起源于一个数学问题。我们并不需要过多的了解函数式编程的历史,要追究它的历史以及函数式编程,关于范畴论、柯里化早就让人立马放弃学习函数式编程了。
对于函数式编程我们所要知道的是,它能将一个行为传递作为参数进行传递。至于其他的,就留给学院派吧。
第二章 Lambda表达式
在第一章的示例中,我们看到在以前想要传递一个行为,我们通常使用的是匿名内部类,而从Java8开始,引入了一种全新更为简洁的方式来支持函数式编程,那就是——Lambda表达式。
我们把第一章中的示例改为Lambda作为本章的开始。
button.addActionListener(event -> System.out.println("button clicked"));
Lambda表达式语法规则主体分为两个部分,中间用“->”右箭头连接,左边代表参数,右边代表函数主体。
2.1 函数式接口
在Java中有一个接口中只有一个方法表示某特定方法并反复使用,例如Runnable
接口中只有run
方法就表示执行的线程任务。
Java8中对于这样的接口有了一个特定的名称——函数式接口。Java8中即使是支持函数式编程,也并没有再标新立异另外一种语法表达。所以只要是只有一个方法的接口,都可以改写成Lambda表达式。在Java8中新增了java.util.function
用来支持Java的函数式编程,其中的接口均是只包含一个方法。
例如Predicate
接口中只包含test
方法,该函数接口接受一个输入参数,返回一个布尔值。
函数式接口中的方法可以有参数、无参数、有返回值、无返回值。
() -> System.out.println("hellobug")
,表示无参数。event -> System.out.println("hellobug")
,表示只有一个参数。(x, y) -> {System.out.println(x); System.out.println(y);}
,表示两个参数,可以不必指定参数类型,为了更清楚地表达意图,最好还是加上参数类型,(String x, String y) -> {System.out.println(x); System.out.println(y);}
。
接下来我们来编写一个带参数且有返回的函数式接口。
package com.coderbuff.chapter2_lambda.function;
/**
* 函数式接口
* @FunctionalInterface 注解只是为了表明这是一个函数式接口,函数式接口只能包含一个方法。
* @author okevin
* @date 2020/3/14 23:32
*/
@FunctionalInterface
public interface FunctionalInterfaceDemo {
boolean test(Integer x);
}
除了@FunctionalInterface注解,其它和一个普通的接口无任何差别。@FunctionalInterface注解只是为了标注这是一个函数式接口,如果标注了@FunctionalInterface注解,此时接口中就只能包含一个方法,因为函数式接口只能包含一个方法。
接着我们在测试类中编写一个方法,方法的参数就是这个函数式接口,这代表了我们将传递行为。
package com.coderbuff.chapter2_lambda.function;
/**
* 按匿名类的方式使用一个函数式接口,传递行为
* @author okevin
* @date 2020/3/14 23:42
*/
public class AnonymousInnerClassTest {
private void testAnonymousInnerClass(FunctionalInterfaceDemo functionalInterfaceDemo) {
Integer number = 1;
boolean result = functionalInterfaceDemo.test(number);
System.out.println(result);
}
}
testAnonymousInnerClass
方法的含义表示将通过FunctionalInterfaceDemo#test
方法判断传入的参数1返回布尔值。
我们应该如何通过Lambda表达式来使用这个函数式接口呢?
前面我们说了,这个参数代表了我们将传递一个行为,这个行为决定了1返回是true还是false,我们先通过匿名内部类实现这个接口。
package com.coderbuff.chapter2_lambda.function;
/**
* 按匿名类的方式使用一个函数式接口,传递行为
* @author okevin
* @date 2020/3/14 23:42
*/
public class AnonymousInnerClassTest {
private void testAnonymousInnerClass(FunctionalInterfaceDemo functionalInterfaceDemo) {
Integer number = 1;
boolean result = functionalInterfaceDemo.test(number);
System.out.println(result);
}
public static void main(String[] args) {
AnonymousInnerClassTest anonymousInnerClassTest = new AnonymousInnerClassTest();
anonymousInnerClassTest.testAnonymousInnerClass(new FunctionalInterfaceDemo() {
@Override
public boolean test(Integer x) {
if (x > 1) {
return true;
}
return false;
}
});
}
}
这是在Java8之前通过匿名内部类实现行为的传递,在有了Lambda表达式后,通过上文的Lambda表达式语法规则,这是一个参数+一个返回(Lambda表达式中有返回值时return可以省略),并且有多行代码。
anonymousInnerClassTest.testAnonymousInnerClass(number -> {
if (number > 1) {
return true;
}
return false;
});
关注公众号(CoderBuff)回复“stream”抢先获取PDF完整版。
近期教程:
《On Java 8》 ↩︎
Java8函数式编程以及Lambda表达式的更多相关文章
- Java8函数式编程和lambda表达式
文章目录函数式编程JDK8接口新特性函数接口方法引用函数式编程函数式编程更多时候是一种编程的思维方式,是一种方法论.函数式与命令式编程区别主要在于:函数式编程是告诉代码你要做什么,而命令式编程则是告诉 ...
- Java 函数式编程(Lambda表达式)与Stream API
1 函数式编程 函数式编程(Functional Programming)是编程范式的一种.最常见的编程范式是命令式编程(Impera Programming),比如面向过程.面向对象编程都属于命令式 ...
- Java 函数式编程和Lambda表达式
1.Java 8最重要的新特性 Lambda表达式.接口改进(默认方法)和批数据处理. 2.函数式编程 本质上来说,编程关注两个维度:数据和数据上的操作. 面向对象的编程泛型强调让操作围绕数据,这样可 ...
- Java8函数式接口以及lambda表达式实践
罗列一下遇到可以转换成lamada表达式的场景,仅供参考,如有更好的方式,欢迎在评论区留言. 1.计算订单总金额 订单总金额一般是在后台循环叠加每个购买商品的金额已获取到,通常的方式如下 BigDec ...
- Python函数式编程:Lambda表达式
首先我们要明白在编程语言中,表达式和语句的区别. 表达式是一个由变量.常量.有返回值的函数加运算符组成的一个式子,该式子是有返回值的 ,如 a + 1 就是个表达式, 单独的一个常量.变量 或函数调 ...
- C# 函数式编程 —— 使用 Lambda 表达式编写递归函数
最近看了赵姐夫的这篇博客http://blog.zhaojie.me/2009/08/recursive-lambda-expressions.html,主要讲的是如何使用 Lambda 编写递归函数 ...
- 函数式编程--使用lambda表达式
前面一篇博客我们已经说到了,lambda表达式允许使用更简洁的代码来创建只有一个抽象方法的接口的实例.现在我们来写一段java的命令者模式来自己研究下lambda表达式的语法. 这里重复下命令者模式: ...
- Java函数式编程和lambda表达式
为什么要使用函数式编程 函数式编程更多时候是一种编程的思维方式,是种方法论.函数式与命令式编程的区别主要在于:函数式编程是告诉代码你要做什么,而命令式编程则是告诉代码要怎么做.说白了,函数式编程是基于 ...
- Java8函数式接口和Lambda表达式
两者关系: Lambda表达式就是函数式接口(FunctionalInterface)实现的快捷方式,它相当于函数式接口实现的实例,因为在方法中可以使用Object作为参数,所以把Lambda表达式作 ...
随机推荐
- MicrosoftOfficeProfessionalPlus2013傻瓜式激活工具
用微软的office系列,总是提示需要输入秘钥,直接找个破解软件破解算了. 破解软件地址:http://www.3322.cc/soft/10037.html 1.下载解压: 2.点击office系列 ...
- APP内计费规范出台 手游乱收费现象能被遏制?
手游乱收费现象能被遏制?" title="APP内计费规范出台 手游乱收费现象能被遏制?"> 在一个混乱.无秩序的环境中竞争,虽然有可能不择手段地获取更多的利益,但 ...
- Python---10小结
因一边上班一边自学python,一旦忙起来,python就会放两天,可是2天后之前学的内容就会有点忘记. 今天把python的各种启动方法总结一下; 我的文档路径: ------- 1打开文件所在的c ...
- 通过zxing生成二维码
二维码现在随处可见,在日常的开发中,也会经常涉及到二维码的生成,特别是开发一些活动或者推广方面的功能时,二维码甚至成为必备功能点.本文介绍通过 google 的 zxing 包生成带 logo 的二维 ...
- Python如何规避全局解释器锁(GIL)带来的限制
编程语言分类概念介绍(编译型语言.解释型语言.静态类型语言.动态类型语言概念与区别) https://www.cnblogs.com/zhoug2020/p/5972262.html Python解释 ...
- 芮勇博士荣获2016年IEEE 计算机学会技术成就奖
微软亚洲研究院常务副院长 芮勇 日前,电气电子工程师学会(the Institute of Electrical and Electronics Engineers, IEEE)计算机学会(Comp ...
- textarea 实现高度自动增长
有时候希望textarea 能够自动调整高度来适应输入的内容 网上看到了很多解决方案,比如动态创建一个隐藏的div,当用户输入的时候将textarea的内容绑定到div,由于div的高度会自动撑开,因 ...
- 2020年JAVA大厂笔经面经
个人简介 Java后台开发方向. 非计算机专业硕士,专业涉及到一些开发. 实验室项目主要是Java Web系统,挖掘小亮点. 无实习经验. 闲话唠嗑 回顾这几个月,宛若梦一场. 一开始心态不好 ...
- sql--自链接(推荐人)
表1: 需求:查出推荐人,和被推荐人 1.通过group_concat函数和分组,查出每个id推荐的人有哪些 select group_concat(u_name, u_id) as referce_ ...
- Newman+Jenkins实现接口自动化测试
目录 一.是什么Newman 二.如何安装 三.如何使用 1.运行本地文件 2.运行在线文件 3.以node.js库运行 4.导出报告 四.命令行测试真实接口 1.导出collection文件 2.导 ...