lambda表达式的引入
对一个字符串数组按照字符串的长度由小到大排序的代码如下(向sort方法中传递一个Comparator对象):
import java.util.Arrays;
import java.util.Comparator;
public class LambdaTest {
public static void main(String[] args) {
String[] nums = new String[]{"abc" ,"bcsd","qweqds"};
Arrays.sort(nums, new CMP());
for(String s : nums)
System.out.println(s);
}
}
class CMP implements Comparator<String> {
@Override
public int compare(String a, String b) {
return a.length() - b.length();
}
}
在jdk8之前,是不支持函数式编程的。必须将一个需要用的的函数(代码块)传递给某一个对象进行使用,即该对象的类需要有一个方法能包含所需要的代码块。
lambda表达式的语法
把上述代码写成lambda表达式的形式如下:
public class LambdaTest {
public static void main(String[] args) {
String[] nums = new String[]{"abc" ,"bcsd","qweqds"};
Arrays.sort(nums, (String a, String b) -> a.length() - b.length());
//或Arrays.sort(nums, (a, b) -> a.length() - b.length());
for(String s : nums)
System.out.println(s);
}
}
lambda表达式的基本语法如下:
- 参数,箭头,一个表达式
(String a, String b) -> a.length() - b.length()
//不能写return,如果使用return,即使只有一个表达式,也需要用{}括起来
- 参数,箭头,{多个语句}
(a, b) -> {
//形参不写类型,可以从上下文推断出来
int res = a.length() - b.length();
return res;
}
注意:如果没有参数,也需要写括号,如果只有一个参数,则括号可以省略;
如:
() -> System.out.println("hello world!");
a -> System.out.println("hello world!"); //a的类型必须可以从上下文推断出来
函数式接口
函数式接口:
- 是一个只包含一个抽象方法的接口。
- 可以包括其他的default方法、static方法、private方法。
- 由于只有一个为实现的方法,所以lambda表达式会自动填充上这个未实现的方法。
- 采用lambda表达式,可以自动创建出一个(伪)嵌套类的对象(没有实际的嵌套类class文件的产生),然后使用,比真正的嵌套类更加轻量,更加简洁高效。
lambda表达式:
Comparator<String> c = (a, b) -> a.length() - b.length();
匿名内部类:
Comparator<String> c = new Comparator<String>() {
@Override
public int compare(String a, String b) {
return a.length() - b.length();
}
};
lamda表达式(匿名函数)自动成为接口方法的实现。
方法引用
- 表达式
System.out::println
是一个方法引用(method reference),等价于lambda表达式x->System.out.println(x)
。 - 如果想对字符串排序忽略大小写,可以使用表达式:
Arrays.sort(strings, String::compareToIgnoreCase)
。 - 要用:;操作符分隔方法名与对象或类名。主要用3种。
- object::instanceMethod
- Class::staticMethod
- Class::instanceMethod
- 在第2种情况中,方法引用等价于提供方法参数的lambda表达式。如:
Math::pow
等价于(x, y) -> Math.pow(x, y)
。 - 在第3种情况中,第1个参数会成为方法的目标。例如,
String::compareToIgnoreCase
等价于(x, y) -> x.compareToIgnoreCase(y)
。 this::equals
等价于x -> this.equals(x)
。super
同理。