Java 8中比较大的改变就是引入了Lambda 表达式和Stream API,这使得Java可以进行函数式编程(functional programming)。
1. 什么是函数式编程
函数式编程和面向对象编程、面向过程编程一样,都是一种如何编程的方法论,它主要的思想是函数是“第一等公民”,和其他数据类型一样,可以被赋值和传递。函数式编程具有代码简洁,易于理解,易于"并发编程"等优点。关于它的简单介绍,可以参见函数式编程初探。
2. 什么是Lambda 表达式
An expression with parameter variables has been called a lambda expression. --- From Core Java Volume I--Fundamentals (10th Edition)
从上面的定义可以知道,带有参数的表达式就是lambda 表达式。例如(String first, String second) -> first.length() - second.length()
就是一个lambda 表达式。下面我们介绍Java中的lambda 表达式。
2.1 问题
public interface ActionListener {
void actionPerformed(ActionEvent e);
}
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ui.dazzle(e.getModifiers());
}
});
上面的代码使用了匿名类,但匿名类具有冗余的语法,不够简洁,存在“高度问题”。能不能让代码更加简单易读?
2.2 解决办法
通过观察我们发现,ActionListener只有一个抽象方法,我们把只有一个抽象方法的接口叫做函数式接口(functional interface),这时你就可以使用Lambda 表达式。因而我们可以把代码简化为:
button.addActionListener(e -> ui.dazzle(e.getModifiers()));
代码看起来简洁多了。你会发现Lambda 表达式并不是很玄的东西,不过是让代码看起来更加简洁的语法糖而已。
2.3 方法引用(method reference)
有时,已经有一个方法做了你期望做的事,这时我们可以用另一个语法来进一步简化代码。
// 使用范例
object::instanceMethod
Class::staticMethod
Class::instanceMethod
Timer t = new Timer(1000, event -> System.out.println(event));
Timer t = new Timer(1000, System.out::println);
上面两种写法是同等的。System.out::println
是方法引用,等同于lambda表达式x -> System.out.println(x)
。
另一个例子:String::compareToIgnoreCase
等价于(x, y) -> x.compareToIgnoreCase(y)
3. Stream API
为了能够进行函数式编程,光有Lambda 表达式这个语法糖是不行的,因而Java 8 又提供了Stream API,这是一个非常重大的更新,可以用函数式编程的思想方便地实现对集合(collections)的各种操作。掌握Stream API需要不断实践,可以网上查阅这些API的用法,本文对此不再展开,下面是一些例子。
shapes.stream()
.filter(s -> s.getColor() == BLUE)
.forEach(s -> s.setColor(RED));
List<Shape> blue = shapes.stream()
.filter(s -> s.getColor() == BLUE)
.collect(Collectors.toList());
Set<Box> hasBlueShape = shapes.stream()
.filter(s -> s.getColor() == BLUE)
.map(s -> s.getContainingBox())
.collect(Collectors.toSet());
int sum = shapes.stream()
.filter(s -> s.getColor() == BLUE)
.mapToInt(s -> s.getWeight())
.sum();
写在最后
技术的核心思想一般都是简单和通俗易懂的,别被它花哨的名词唬住了,互联网擅长制造概念。当然由于水平有限,如果有什么不对的地方,也欢迎大家指正。
Reference:
1.Core Java Volume I--Fundamentals (10th Edition) Cay S. Horstmann
2.http://www.cnblogs.com/figure9/p/java-8-lambdas-insideout-language-features.html
3.http://ju.outofmemory.cn/entry/104364