一、lambda表达式简单要点:
1,一个lambda表达式是一个带有参数的代码块
2,可以使用lambda表达式使得代码块在适当的某个时间点执行
3,lambda表达式可以被转换为函数式接口
二、lambda表达式的语法
1,参数,箭头->,以及一个表达式或代码块
(parameters) -> expression
(parameters) -> {statements;}
例子:
考虑一个自定义的比较器进行排序,按照字符串的长度来排序的规则。
1,最初的不使用lambda方式:实现一个Comparator
import java.util.Arrays;
import java.util.Comparator;
public class LengthComparator implements Comparator<String> {
public int compare(String first, String second) {
return Integer.compare(first.length(), second.length());
}
public static void main(String[] args) {
String[] strings = { "hello", "world", "java" };
Arrays.sort(strings, new LengthComparator());
Arrays.stream(strings).forEach(System.out::println);
}}
sort方法会一直调用compare方法(底层采用的是TimSort类的binarySort方法),对顺序不对的元素进行重新排序。
在这里其实就是向sort方法传递了一个需要比较元素的代码片段,该代码会被整合到排序逻辑中,而你可能并不关心如何在哪里实现。
2,下面可以进行引入lambda表达式。
Integer.compare(first.length(), second.length())是一个有返回值的方法,first和sencond是它的参数,而且是String类型。
根据lambda表达式的语法可以如下定义:
(String first, String second) -> Integer.compare(first.length(), second.length())
这个表达式不仅是一个简单的代码块,还指定了必须传递给代码的所有变量。如果把Integer.compare方法自己实现,可以是如下代码块方式:
(String first, String second) -> {
if (first.length() < second.length()) return -1;
else if (first.length() > second.length()) return 1;
else return 0;
}
3,使用lambda表达式(函数式接口转换)
public static void main(String[] args) {
String[] strings = { "hello", "world", "java" };
Arrays.sort(strings, (a, b) -> Integer.compare(a.length(), b.length()));
Arrays.stream(strings).forEach(System.out::println);
}
此处lambda表达式的参数类型是可以被推导的,所以可以省略它们的类型。
因为它们是名义上的参数,所以不必去纠结他们的名字。
在这个表达式背后,Arrays.sort方法会接收一个实现了Compator接口的类的实例。
调用该对象的compare方法会执行lambda表达式中的代码。这些对象和类的管理完全依赖于如何实现,因此比传统的内部类效率更高。
最好将一个lambda表达式想象成一个函数,而不是一个对象,并记住它可以被转换成一个函数式接口。
事实上,函数式接口的转换是你在Java中使用lambda表达式能做的唯一一件事。
三、参考文献
《Java SE 8 for the Really Impatient》