Java Lambda表达式教程
Java8引入了Lambda表达式,它是引入的最大(如果不是最大的)特性之一,因为Lambda表达式使函数式编程成为可能,它使代码更加简洁,并大大简化了整个代码实现。
例如,当我们必须使用匿名类,并且该类非常简单,例如只包含一对(甚至更少)方法时,我们将遇到一个非常不清晰且难以阅读/维护的语法。这就是Lambda表达式的作用开始发挥作用的时候。
比较Lambda表达式的使用和不使用Lambda表达式
假设有一个类有一个默认情况下按升序对元素排序的类(例如Comparator)。此类使用compare对元素进行排序。让我们超越它。
不使用Lambda表达式
Comparator<Double> sorter = new Comparator<Double>() { @Override public int compare(Double x, Double y) { return y.compareTo(x); } };
Lambda表达式的使用
Comparator<Double> lambdaComparator = (x, y) -> y.compareTo(x);
我相信你能注意到这两种方法的区别。这两种方法的结果是相同的,即颠倒这个方法对元素排序的顺序(从升序到降序,这是在开比较器的玩笑!)。
所以只要看一下这个例子,使用lambda表达式的一个关键优势就是可以减少要键入的代码。这对我们这些懒惰的程序员来说是一个很好的例子。然而,有人可能会说,由于这种简单性,它实际上使记住语法更加困难。这是真的,所以这是一个缺点。一开始,语法可能是一个难以记住的类型,但是一旦你记住了它,你就可以编写干净的代码来实现函数接口。
让我们看看Lambda表达式的更多示例。
首先,语法,就像我之前说的,一开始有点吓人。
如果要“重写”的函数没有任何参数,则只需键入()->{body}。另一方面,如果我们只有1个参数,那么我们将键入(x)->{body}。对于两个以上的参数也是一样的,我们将有(x,y,z…)->{body}。
循环
import java.util.*; public class LambdaExpressionDemo { public static void main(String[] args) { List<int> listOfNumbers = new ArrayList<int>(); listOfNumbers.add(1); listOfNumbers.add(2); listOfNumbers.add(3); listOfNumbers.add(4); listOfNumbers.add(5); listOfNumbers.add(6); listOfNumbers.add(7); listOfNumbers.add(8); listOfNumbers.forEach( (num) -> System.out.println(num) ); } }
请注意,在forEach循环的主体中,我省略了{}大括号。那是因为身体只有一条线。如果我有两行或者更多行,比如另一个print语句,那么我会有大括号,如下所示:
import java.util.*; public class LambdaExpressionDemo { public static void main(String[] args) { List<int> listOfNumbers = new ArrayList<int>(); listOfNumbers.add(1); listOfNumbers.add(2); listOfNumbers.add(3); listOfNumbers.add(4); listOfNumbers.add(5); listOfNumbers.add(6); listOfNumbers.add(7); listOfNumbers.add(8); listOfNumbers.forEach( (num) -> { System.out.println(num); System.out.println(num); ); } }
Lambda表达式返回值
也可以像在方法中一样,使用lambda表达式返回值。这里需要注意的一个关键是return关键字是可选的。你可以省略它,编译器知道它的工作。
它的语法与我们以前使用的语法相似。
(x, y) -> { return x > y; }
因此,如果我们再看看Lambda表达式提供了什么,我们可以得出这样的总结:它为我们提供了可选的类型声明(不需要声明参数的类型)、可选的大括号、可选的返回关键字(因为如果主体的返回值有一个signle表达式,编译器会自动返回值)和可选的括号围绕参数。