java 8 提供了函数式编程,使得代码变得更加优雅,更加简洁。
首先,lambda表达式只能提供对一个方法的接口的编程,当然了,不算默认方法和静态方法。
如:
public static void main(String[] args) {
Comparator<Integer> comparator = (a,b)->a-b;
}
如果实现的代码很多,可以使用花括号括起来,如:
public static void main(String[] args) {
Comparator<Integer> comparator = (a,b)->{
return a-b;
};
}
就这么简单就实现了比较器Comparator的compare接口,因为一个lambda只能实现一个接口,所以要求必须实现的接口方法只能为一个。相比较以前的匿名内部类实现接口的方式,少了方法名称,入参以及new Comparator等,并且如果只是一行代码,还可以省略return 关键字,如果有返回值的话,默认返回值就是那一行代码的值,这些就使得代码更加简洁。
其实,个人认为,java8的lambda表达式,其实是编译器隐式的搜寻到了要实现的方法,并实现了该方法,不必程序员显示地指定,从这一点上说,可以说是编译器更加智能了。因此,同样的,与匿名内部类实现接口一样,对于外部变量传入的参数。会被隐式地当成final,当然,也可以显式地声明。
如下:
//加final
public static void main(String[] args) {
final int c = 1;
Comparator<Integer> comparator = (a,b)->{
return a-b+c;
};
}
//不加final
public static void main(String[] args) {
int c = 1;
Comparator<Integer> comparator = (a,b)->{
return a-b+c;
};
}
上述两个例子来说实际上是一样的,都被定义成了final。
Lambda表达式还可以当成方法的入参参数,如:
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.sort((a, b) -> a - b);
}
在这段代码中,因为sort方法只有一个Compator接口的参数,因此该lambda表达式默认实现了Compator。感觉简洁了很多,函数竟然可以当成参数传递进去(虽然实际是传进去了一个接口实现对象)。然而,虽然简洁了许多,但是却不难发现,这么做在一定程度上破坏了java语言的方法的重载,使得向后兼容困难。以上述用函数入参做个例子吧。假如使用JDK8的时候,采用了lambda表达式作为比较器,那么这就意味着,java9就不能增加另一个sort(新接口)的方法了,否则在java9的环境下,java8的代码(这里指的是过分依赖编译器智能化,不做显示声明的)不做调整就没法用了,不过,或许有其它法子也不得而知。当然了,这个例子可能有点极端,但是大众化一点来说,谁或多或少都要重载那么几个函数。因此用Lambda表达式入参最好显示声明,否则向后兼容的时候或许会带点麻烦。毕竟编译器变得智能,在某种程度上来说,可靠程度变低了。同时为了克服Lambda表达式的脆弱性,java8新增了一个@FunctionalInterface注解,该注解表明了该接口只能使用一个接口,避免该接口声明了多个普通方法。因此,规则化代码,不过分依赖编译器和人对自身的约束,不过度使用语法糖,是一种很好的习惯(个人认为)。