lambda表达式

函数式接口

函数式接口是指接口中只有一个抽象方法(Java8中接口中可以声明非抽象方法),例如Comparator:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@FunctionalInterface
public interface Comparator<T> {

int compare(T o1, T o2);

//重新声明Object中的方法会让方法不再是抽象方法
boolean equals(Object obj);

default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}

public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
return new Comparators.NullComparator<>(true, comparator);
}

....

}

使用实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//注意:由于带Comparator的sort方法参数声明为泛型,所有无法使用基本类型
Integer word[] = new Integer[]{12,23};
Arrays.sort(word,(e1, e2)-> e1 - e2);

//上面的代码相当于下面的代码,可以看出lambda可以使代码简洁
Integer word[] = new Integer[]{12,23};
Arrays.sort(word, new Comparator<Integer>() {
@Override
public int compare(Integer e1, Integer e2) {
return e1 - e2;
}
});


Predicate<Boolean> isNull = Objects::isNull;
System.out.println(isNull.test(null));
//等同于
Predicate<Boolean> isNull = new Predicate<Boolean>() {
@Override
public boolean test(Boolean aBoolean) {
return Objects.isNull(aBoolean);
}
};
System.out.println(isNull.test(null));

lambda表达式的方法引用

方法引用的三种情况

  • object::instanceMethod(对象方法)
  • Class::staticMethod (静态方法)
  • Class::instanceMethod (对象方法)

前两种情况中,方法引用等价于提供方法参数的lambda,例如Math::pow等价于(x,y)->Math.pow(x,y)

第三种情况,第一个参数会成为方法的目标,例如String::compareToIgnoreCase等价于(x,y)->x.compareToIgnore(y)

lambda表达式的构造器引用

例如A::new是A的构造器引用,至于使用哪一个构造器,取决于上下文。

lambda表达式变量的作用域

1
2
3
4
5
6
public void requestMessage(String text,int delay){
ActionListener actionListener = e -> {
System.out.println(text);//使用变量text
...
};
}

可以把一个lambda表达式转化为包含一个方法的对象,这样自由变量的值就会复制到这个对象的实例变量中去

注意:lambda表达式中捕获的变量必须是最终值;而且在lambda中声明于一个局部变量同名的参数或局部变量是不合法的;在lambda表达式中使用this关键字时,是指创建这个lambda表达式的方法的this参数

常用的函数式接口

函数式接口 参数类型 返回类型 抽象方法名 描述
Runnable void run 作为无参数或返回值的动作运行
Predicate<T> T boolean test 布尔值函数
BiPredicate<T,U> T,U boolean test 有两个参数的boolean函数
Supplier<T> T get 提供一个T型的值
Consumer<T> T void accept 处理一个T类型的值
BiConsumer<T,U> T,U void accept 处理T和U类型的值
Function<T,R> T R apply 由T转化为R类型
BiFunction<T,U,R> T,U R apply 由T,U类型转化为R类型
UnaryOperator<T> T T applay UnaryOperator继承Function,由T类型返回T类型
BinaryOperator<T> T,T T applay BinaryOperator继承BiFunction

基本类型的函数式接口

为了减少自动装箱,一个尽量使用基本类型的函数式接口,如图:

函数式接口