Lambda 表达式是 Java 8 一个非常重要的新特性。它像方法一样,利用很简单的语法来定义参数列表和方法体。目前 Lambda 表达式已经成为高级编程语言的标配,像 Python,Swift 等都已经支持 Lambda 表达式。
在 Java 8 的实现中,Lambda 表达式其本质只是一个 "语法糖",经过编译器推断和处理,将其转换包装为常规的 Java 代码,因此就像题目所写的那样,可以让你的代码更为简洁。
Lambda 表达式的基本语法:(parameters) -> expression 或 (parameters) -> {statements;}
Lambda 表达式并不是一个方法,它可以用来定义了一个代码块,形式上很像是 Java 的匿名内部类。Lambda 表达式通常会赋值给一个函数式接口,函数式接口是指只有一个抽象方法的接口。Lambda 表达式可以通过上下文环境来推断变量类型, 因此在使用时尽量不人为明确的指定变量类型。
举例来看,假设我们有一个 List<String> 类型的列表 list,如果要遍历并打印列表内容,Java 7 以前的代码如下:
- 1
- for (String s: list) {
- 2 System.out.println(s);
- 3
- }
Java 8 来实现的话:
- 1 list.forEach((s) - >System.out.println(s));
或者
- 1 list.forEach(System.out: :println);
再看一个例子,假设我们要对 list 进行排序,Java 7 的代码如下:
- 1 Collections.sort(list, new Comparator() {
- 2@Override 3 public int compare(String p1, String p2) {
- 4
- return p1.compareTo(p2);
- 5
- }
- 6
- });
Java 8 来实现的话:
- 1 Collections.sort(list, (String p1, String p2) - >p1.compareTo(p2));
需要注意的是,Lambda 表达式可以做参数类型推断,这里我们可以充分利用这一点,p1 和 p2 参数前面的 String 是不需要的,因此可以简化一步如下:
- 1 Collections.sort(list, (p1, p2) - >p1.compareTo(p2));
更进一步:
- 1 list.sort((p1, p2) - >p1.compareTo(p2));
是不是简洁了很多:)
Lambda 表达式也可以用来代替匿名类。例如我们要实现 Runnable 接口,Java 7 的代码如下:
- 1 new Thread(new Runnable() {
- 2@Override 3 public void run() {
- 4 System.out.println("Hello world !");
- 5
- }
- 6
- }).start();
Java 8 来实现的话:
- 1 new Thread(() - >System.out.println("Hello world !")).start();
用 Lambda 表达式来实现 Runnable,将五行代码转换成一行语句。
合理使用 Lambda 表达式,不仅能简化几行代码,还能做到合理的代码抽象。当我们在实现的两个很大的方法时,如果大部分的代码都是相同的,只有一小点代码不一样时,我们可以通过将 Lambda 表达式作为参数传入,以达到不同表意的目的。
前面提到的函数式接口(Functional Interfaces),它表示只有一个抽象方法的接口,可以用来指向 Lambda 表达式。例如:
- 1 Consumer c = (s) - >System.out.println(s);
Java 8 在 java.util.function 包中实现了新的几个:
另外,我们最为熟悉的函数式接口还有:
通常我们应该尽量使用标准的函数式接口,如果我们要自定义的话,可以使用 @FunctionalInterface 注解,例如:
- 1@FunctionalInterface 2 public interface funcInterface {
- 3 public abstract B op(A a);
- 4
- }
在将函数式接口作为参数时,需要注意尽量避免方法重载。由于 Lambda 表达式根据所在环境的目标类型来决定 Lambda 表达式的类型(也就是 Target Typing), 因此方法重载有时会导致编译器犯晕。我们可以使用不同的方法名来解决这个问题。
在这里,我们还需要澄清几点:
Java 8 还增强了对集合数据的批量操作 Stream,通常会和 Lambda 表达式一起使用。Lambda 表达式和 Stream 可以说是 Java 语言从添加泛型 (Generics) 和注解 (annotation) 以来最大的变化了。下一篇文章将重点介绍 Stream。
来源: http://www.cnblogs.com/pkufork/p/java_8_lambda.html