1. Lambda表达式的基本语法

Java8中引入了一个新的操作符 "->" 该操作符称为箭头操作符或 Lambda 操作符 箭头操作符将 Lambda 表达式拆分成两部分:
左侧:Lambda 表达式的参数列表
右侧:Lambda 表达式中所需执行的功能, 即 Lambda 体
比如我们使用Comparator的时候,以前是使用匿名内部类的方式,现在我们可以使用Comparator<Integer> com = (x, y) -> Integer.compare(x, y);的形。
其中,(x,y)是输入的参数,他们的参数类型可以省略不写,因为会根据前面的Integer进行类型推断。后面的方法体因为只有一句所以也省略{},然后 return 也可以省略。
其完整写法是:

Comparator<Integer> 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> : 消费型接口,对类型为T的对象应用操作

    void accept(T t);

Supplier<T> : 供给型接口,返回类型为T的对象

   T get(); 

Function<T, R> : 函数型接口,对类型为T的对象进行操作,返回类型为R 的对象

     R apply(T t);

Predicate<T> : 断言型接口,确定类型为T的对象是否满足某约束

     boolean test(T t);

当然这四个接口还衍生出很多子接口。

3. 方法引用

当要传递Lambda体的操作,已经有实现的方法了,就可以使用方法引用!(方法引用所使用方法的入参和返回值与lambda表达式实现的函数式接口的入参和返回值一致。) 可以将方法引用理解为 Lambda 表达式的另外一种表现形式

方法引用就是使用::操作符将把对象或者类的名字和方法名连接起来。有一下三种使用情况:

  • 对象的引用 :: 实例方法名
Employee emp = new Employee(101, "张三", 20, 9999);
#Lambda表达式
Supplier<String> sup = () -> emp.getName();
System.out.println(sup.get());
#方法引用
Supplier<String> sup2 = emp::getName;
System.out.println(sup2.get());
  • 类名 :: 静态方法名
#Lambda表达式
Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
#方法引用
Comparator<Integer> com2 = Integer::compare;
  • 类名 :: 实例方法名

Lambda 的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式ClassName::MethodName

#Lambda表达式
BiPredicate<String, String> bp = (x, y) -> x.equals(y);
System.out.println(bp.test("abcde", "abcde"));
#方法引用
BiPredicate<String, String> bp2 = String::equals;
System.out.println(bp2.test("abc", "abc"));

#Lambda表达式
Function<Employee, String> fun = (e) -> e.show();
System.out.println(fun.apply(new Employee()));
#方法引用
Function<Employee, String> fun2 = Employee::show;
System.out.println(fun2.apply(new Employee()));

4. 构造器引用

前提:构造器引用 :构造器的参数列表,需要与函数式接口中参数列表保持一致
使用:类名 :: new

#Lambda表达式
Supplier<Employee> sup = () -> new Employee();
System.out.println(sup.get());    
#构造器引用
Supplier<Employee> sup2 = Employee::new;
System.out.println(sup2.get());

5. 数组引用

使用:type[] new

# Lambda表达式
Function<Integer, String[]> fun = (args) -> new String[args];
String[] strs = fun.apply(10);
System.out.println(strs.length);    
数组引用
Function<Integer, Employee[]> fun2 = Employee[] :: new;
Employee[] emps = fun2.apply(20);
System.out.println(emps.length);

njitzyd
58 声望7 粉丝