Java Lambda表达式:一旦学会就回不去了,谁用谁知道
作者:Yogen Rai
译者:helloworldtang
自Java 8发布以来,许多样板代码都可以使用Lambda表达式替代。我真的想在Java中发表一篇关于 流 的文章,但是如果我们能将流与Lambda表达式结合起来,那么就肯定会带来真正的价值。因此,我就先写一下如何使用Lambda表达式。
函数式接口
一个函数式接口是指一个接口只有一个抽象方法,也称为SAM (Single Abstract Method)【单一的抽象方法】类型。这个概念是在JDK 8中引入的,但是在JDK 8之前就已经有接口符合该定义了。例如, Comparator
接口就只有一个抽象方法: compare()
。
我们可以自定义函数式接口:
@FunctionalInterface
interface Calculator<T,R> {
R calculate(T a, T b);
}
在这里, @FunctionalInterface
注解由编译器检查。因此,如果该接口不是仅仅只包含一个抽象方法,那么就会出现编译错误。
温馨提示: 包括0个或多个抽象方法都会编译错误
在为Lambda表达式自定义函数式接口时,可以不使用这个注解,但是,像其他注解(例如 @Override
)一样,使用 @FunctionalInterface
是最佳实践,因为该注解会告诉编译器需要检查这个函数式接口是否有效——否则,这个函数式接口的合法性检查将被忽略,直到实际运行的时候。
那么,什么是Lambda表达式呢?
Lambda表达式是函数式接口的内联实现,可以替代某些匿名内部类。
Lambda表达式由三部分组成:
Lambda参数列表 [一个或多个]
->
代码块 [如果多于一个语句,需要用花括号括起来{...} ]
[可以包含自由变量;自由变量的值由本地变量或实例变量提供]
温馨提示: 自由变量:在Lambda表达式作用域之外定义的变量
例如:
(a,b) -> a + b; //传入两个数字类型的参数a和b,返回另一个数字:两个入参相加的结果
(String str) -> System.out.println(str); //在控制台打印传入的字符串
上例中,第一个Lambda表达式的等价形式如下所示:
new Calculator<Integer, Integer>() {
@Override
public Integer calculate(Integer a, Integer b) {
return a + b;
}
};
通过对比,您可以看到Lambda表达式是如何帮助我们去除样板代码的。
命名Lambda表达式
Java中的每一个对象都有一个类型;Lambda表达式也是如此。Lambda表达式的类型可以是任何一个函数式接口,其中Lambda表达式是具体的值。
命名Lambda表达式是通过使用适当的函数式接口作为其类型,就像命名任何一个普通对象一样。例如:
Calculator<Integer, Integer> adder = (a,b) -> a + b;
上例中,Lambda表达式的名字是 Calculator
类型的 adder
。
温馨提示: 此处我们省略了参数类型,因为如果可以推断出参数类型,就可以省略。
带上参数类型的Lambda表达式如下所示:
Calculator<Integer, Integer> adder = (Integer a,Integer b) -> a + b;
如何使用Lambda表达式
现在,您可以看到Lambda表达式几乎取代了匿名内部类,因为它具备了内部类的基本功能特性:映射到返回值。因此,函数现在是一等公民了。所以:
- Lambda表达式可以像正常的类实例一样来调用自己的方法。例如,
adder
可以直接调用calculate
方法:
Integer sum = adder.calculate(3,4); // sum = 7
2. Lambda表达式可以作为参数传递给方法,并用于方法内的表达式:
// ...
printSum(adder);
// ...
static void printSum(Calculator cal) {
System.out.println(cal.calculate(4,5));
}
3. Lambda表达式可以作为返回值返回:
// ...
Calculator<Integer, Integer> multiplier = getCalculatorFunc();
Integer result = multiplier.calculate(6,9)); // 54
// ...
static Calculator getCalculatorFunc() {
Calculator<Integer, Integer> multiplier = (a, b) -> a * b;
return multiplier;
}
总结
现在,您可以看到如何在维护Java语言面向对象特性的同时,又从函数式编程中获得了好处。Lambda表达式是使用Stream进行函数式编程和编写简洁代码的基础,我将在下一篇文章中继续介绍。直到那时,我们就可以快乐地编码了!
像往常一样,文中用到的代码可以在GitHub上找到。
相关文章
- java除零异常_JAVA异常处理
- java环境变量怎么配置_java环境变量设置怎么配置
- jmeter 中 Client implementation HttpClient4和java区别实践一
- 【说站】java有哪些内置的函数式接口
- 【说站】Java中copyOfRange()的范围拷贝
- 面试:你知道Java性能优化有哪些手段?
- Java递归写法_java递归调用
- expect java,Expect 使用详解「建议收藏」
- Java并发控制机制详解编程语言
- 服务Linux启动Java服务:一步步去完成(linux启动java)
- Java连接Mysql:探索数据库之路。(java链接mysql)
- 运行参数Linux 下修改 Java 运行参数的指南(linux修改java)
- Java多线程知识点详解编程语言
- Java网站在Linux上的运行(java网站linux)
- 极速搭建Java连接SqlServer数据库(java连接sqlserver)
- Java使用Redis实现数据过期管理(redisjava过期)
- 测试Java操作Redis实例(java测试redis)
- 时间设置Java处理Redis过期时间的实践指南(redisjava过期)
- 实现高并发:Java利用Redis秒杀成功(java秒杀redis)
- 使用Java连接SQL Server数据库,快速高效地管理数据(java连接sqlserver数据库)
- Java编程与Oracle技术创造技术价值的奥秘(java编程oracle)
- Java实现与Oracle数据库的无缝整合(java整合oracle)
- java中的正则操作方法总结
- java验证电话号码的方法
- Java读取文件方法大全