本文作者:杨龙,叩丁狼高级讲师。原创文章,转载请注明出处。
为什么要有函数式编程及定义
为什么
- 写出高效的并行代码,比如集合操作。
- 写出出易于维护、更可靠、更不容易出错,比如集合操作。
- 程序员不必再纠缠于匿名内部类的冗繁和可读性。
- 能将函数方便地传递也让编写惰性代码变得容易,惰性代码在真正需要时才初始化变量的值。
定义
函数式编程,就是把一个函数可以作为实参数传递给另一个函数使用。Java8 使用 Lambda 表达式实现函数式编程,一种紧凑的、传递行为的方式。
HelloWorld
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.out.println("button clicked");
}
});
button.addActionListener(event -> System.out.println("button clicked"));
Lambda
术语说明
- Lambda 表达式的参数数量可以 [0, n),类型与数量取决于匿名内部类覆盖接口的方法的形参类型与数量。
- 声明参数时也可以包括类型信息,而且有时编译器不一定能根据上下文推断出参数的类型。
- 只有一个参数时,可以省略圆括号,显式声明参数类型或者有多个参数时,需使用圆括号将参数括起来。
- Lambda 表达式的返回类型可以为任意类型,取决于匿名内部类覆盖接口的方法的返回类型。
- Lambda 表达式的主体若是一行,可以省略花括号,主体内容与普通方法遵循的规则别无二致,可以用返回或抛出异常来退出。
- Lambda 表达式的主体中引用的局部变量必须是 final 或既成事实上的 final 变量。
- Lambda 表达式的类型(或者目标类型)指所在上下文环境的类型,比如将 Lambda 表达式赋值给一个局部变量,或传递给一个方法作为参数,局部变量或方法参数的类型就是 Lambda 表达式的目标类型。Lambda 表达式的类型依赖于上下文环境,是由编译器推断出来的。
button.addActionListener(event -> System.out.println("button clicked"));
// Lambda 表达式的参数个数一个 event,类型为 ActionEvent
// Lambda 表达式的返回类型是 void
// Lambda 表达式的主体是 System.out.println("button clicked")
// Lambda 表达式的目标类型为 ActionListener
String name = getUserName();
button.addActionListener(event -> System.out.println("hi " + name)); // 编译不报错,因为程序隐式地给 name 加了 final 修饰,你也可以手动显示加上
String name = getUserName();
name = formatUserName(name);
button.addActionListener(event -> System.out.println("hi " + name)); // 编译报错,name 是变量
函数接口
定义
函数接口是只有一个抽象方法的接口,用作 Lambda 表达式的类型。
// 下面就是一个函数接口
public interface ActionListener extends EventListener {
public void actionPerformed(ActionEvent event);
}
[图片上传失败...(image-ab5edc-1544061106908)]
指向函数接口的箭头表示参数,若箭头从函数接口射出,则表示方法的返回类型。上图表示 ActionListener 接口,接受一个 ActionEvent 对象,返回空。
Java 中重要的函数接口
接口 | 参数 | 返回类型 |
---|---|---|
Predicate<T> | T | boolean |
Consumer<T> | T | void |
Function<T,R> | T | R |
Supplier<T> | None | T |
UnaryOperator<T> | T | T |
BinaryOperator<T> | (T, T) | T |
想获取更多技术干货,请前往叩丁狼官网:http://www.wolfcode.cn/all_article.html
网友评论