对于任何场景而言,代码量永远都是越少越好,而Java8中提供的Lambda表达式正式简化代码的利器。
参考博客:Java 8 Lambda 表达式详解
参考博客:完美的lambda表达式只有一行
在 Java 8 以前,若我们想要把某些功能传递给某些方法,总要去写匿名类。
manager.addScheduleListener(new ScheduleListener() {
@Override
public void onSchedule(ScheduleEvent e) {
// Event listener implementation goes here...
}
});
Java 是面向对象语言,除了原始数据类型之处,Java 中的所有内容都是一个对象。而在函数式语言中,我们只需要给函数分配变量,并将这个函数作为参数传递给其它函数就可实现特定的功能。JavaScript 就是功能编程语言的典范(闭包)。也就是说Java中方法参数只有两种:一是基础数据类型,一是对象。为了兼容函数式编程,而出现了Lambda表达式。
什么是Lambda表达式
Java 中的 Lambda 表达式通常使用语法是 (argument) -> (body)
,比如:
(arg1, arg2...) -> { body }
(type1 arg1, type2 arg2...) -> { body }
如果Lambda表达式只有一行,则不需要{}
、return
、或者;
,比如:
(Integer e) -> e*2
再比如Lambda要创建一个比较器:
Comparator c = (p1, p2) -> p1.getAge().compareTo(p2.getAge());
甚至于:
Comparator c = Comparator.comparing(Person::getAge);
在这里的::
就是Java中的方法引用。
功能接口
在 Java 中,功能接口(Functional interface)指只有一个抽象方法的接口。
每个 Lambda 表达式都可以隐式地分配给功能接口。例如,我们可以从 Lambda 表达式创建 Runnable 接口的引用,如下所示:
Runnable r = () -> System.out.println("hello world");
编译器会自动将上面的代码编译为:
new Thread(
() -> System.out.println("hello world")
).start();
Lambda 表达式的例子
线程初始化
// Old way
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello world");
}
}).start();
// New way
new Thread(
() -> System.out.println("Hello world")
).start();
事件处理
// Old way
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Hello world");
}
});
// New way
button.addActionListener( (e) -> {
System.out.println("Hello world");
});
遍例输出(方法引用)
// old way
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
for (Integer n : list) {
System.out.println(n);
}
// 使用 -> 的 Lambda 表达式
list.forEach(n -> System.out.println(n));
// 使用 :: 的 Lambda 表达式
list.forEach(System.out::println);
逻辑操作
package com.wuxianjiezh.demo.lambda;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Main {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
System.out.print("输出所有数字:");
evaluate(list, (n) -> true);
System.out.print("不输出:");
evaluate(list, (n) -> false);
System.out.print("输出偶数:");
evaluate(list, (n) -> n % 2 == 0);
System.out.print("输出奇数:");
evaluate(list, (n) -> n % 2 == 1);
System.out.print("输出大于 5 的数字:");
evaluate(list, (n) -> n > 5);
}
public static void evaluate(List<Integer> list, Predicate<Integer> predicate) {
for (Integer n : list) {
if (predicate.test(n)) {
System.out.print(n + " ");
}
}
System.out.println();
}
}
Stream API 示例
// old way
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
for(Integer n : list) {
int x = n * n;
System.out.println(x);
}
// new way
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
list.stream().map((x) -> x*x).forEach(System.out::println);