1. Lambda表达式的基本语法
Java8中引入了一个新的操作符 "->" 该操作符称为箭头操作符或 Lambda 操作符 箭头操作符将 Lambda 表达式拆分成两部分:
左侧:Lambda 表达式的参数列表
右侧:Lambda 表达式中所需执行的功能, 即 Lambda 体
比如我们使用Comparator的时候,以前是使用匿名内部类的方式,现在我们可以使用Comparator
的形。
其中,(x,y)
是输入的参数,他们的参数类型可以省略不写,因为会根据前面的Integer
进行类型推断。后面的方法体因为只有一句所以也省略{}
,然后 return
也可以省略。
其完整写法是:
Comparator com =
(Integer x,Integer y) -> { return Integer.compare(x, y);};
2. 函数式接口
只包含一个抽象方法的接口,称为函数式接口。在java8中,函数式接口会被@FunctionalInterface
注解。
Lambda表达式的使用是需要函数式接口的支持。
在jdk8中,接口中方法是可以使用default修饰的方法实现,这个方法不会影响该接口成为函数式接口。
案例:
#自定义一个函数式接口
@FunctionalInterface
public interface MyFun {
public Integer getValue(Integer num);
}
#
public void test6(){
Integer num = operation(100, (x) -> x * x);
System.out.println(num);
System.out.println(operation(200, (y) -> y + 200));
}
public Integer operation(Integer num, MyFun mf){
return mf.getValue(num);
}
}
2.1 java内置的四大核心函数式接口
Consumer
: 消费型接口,对类型为T的对象应用操作 void accept(T t);
Supplier
: 供给型接口,返回类型为T的对象 T get();
Function
: 函数型接口,对类型为T的对象进行操作,返回类型为R 的对象 R apply(T t);
Predicate
: 断言型接口,确定类型为T的对象是否满足某约束 boolean test(T t);
当然这四个接口还衍生出很多子接口。
3. 方法引用
当要传递Lambda体的操作,已经有实现的方法了,就可以使用方法引用!(方法引用所使用方法的入参和返回值与lambda表达式实现的函数式接口的入参和返回值一致。) 可以将方法引用理解为 Lambda 表达式的另外一种表现形式
方法引用就是使用::
操作符将把对象或者类的名字和方法名连接起来。有一下三种使用情况:
- 对象的引用 :: 实例方法名
Employee emp = new Employee(101, "张三", 20, 9999);
#Lambda表达式
Supplier sup = () -> emp.getName();
System.out.println(sup.get());
#方法引用
Supplier sup2 = emp::getName;
System.out.println(sup2.get());
- 类名 :: 静态方法名
#Lambda表达式
Comparator com = (x, y) -> Integer.compare(x, y);
#方法引用
Comparator com2 = Integer::compare;
- 类名 :: 实例方法名
Lambda 的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式ClassName::MethodName
#Lambda表达式
BiPredicate bp = (x, y) -> x.equals(y);
System.out.println(bp.test("abcde", "abcde"));
#方法引用
BiPredicate bp2 = String::equals;
System.out.println(bp2.test("abc", "abc"));
#Lambda表达式
Function fun = (e) -> e.show();
System.out.println(fun.apply(new Employee()));
#方法引用
Function fun2 = Employee::show;
System.out.println(fun2.apply(new Employee()));
4. 构造器引用
前提:构造器引用 :构造器的参数列表,需要与函数式接口中参数列表保持一致
使用:类名 :: new
#Lambda表达式
Supplier sup = () -> new Employee();
System.out.println(sup.get());
#构造器引用
Supplier sup2 = Employee::new;
System.out.println(sup2.get());
5. 数组引用
使用:type[] new
# Lambda表达式
Function fun = (args) -> new String[args];
String[] strs = fun.apply(10);
System.out.println(strs.length);
数组引用
Function fun2 = Employee[] :: new;
Employee[] emps = fun2.apply(20);
System.out.println(emps.length);