函数式接口和Lambda表达式

1、函数式接口

只包含一个抽象方法的接口称为函数式接口。可以在接口上使用@FunctionalInterface注解检查是否是一个函数式接口。只要一个对象是函数式接口的实例,那么该对象就可以用Lambda表示

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}
函数式接口 参数类型 返回类型 用途 Consumer<T> 消费型接口 T void 对类型T的对象应用操作 包含方法:void accept(T t) Supplier<T> 供给型接口 无 T 返回类型为T的对象 包含方法:T get() Function<T,R> 函数型接口 T R 对类型为T的对象应用操作,并返回结果类型为R. 包含方法:R apply(T t) Predicate<T> 断定型接口 T boolean 确定类型为T的对象是否满足某约束,并返回boolean值 包含方法:boolean test(T t)
JAVA内置四大核心函数接口

2、Lambda表达式

2.1、演变过程

以实现线程Runnable接口为例

2.1.1、常规写法

public static void main(String[] args) {
        new Thread(new MyData()).start();
 }

public class MyData implements Runnable{
    @Override
    public void run() {
        System.out.println("实现Runnable接口");
    }
}

2.1.2、演变为匿名内部类写法

public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("实现Runnable接口");
            }
        };
        new Thread(runnable).start();
    }

2.1.3、使用lambda写法

public static void main(String[] args) {
        Runnable runnable = () -> System.out.println("实现Runnable接口");
        new Thread(runnable).start();
    }

2.2、语法

操作符:->

左侧:指定Lambda表达式需要的参数列表

右侧:指定了Lambda体,即抽象方法的实现逻辑

public static void main(String[] args) {
     
        // 如果参数多个需要(),如果lambda体有多个需要{},参数类型可省略
        Comparator<Integer> comparator = (Integer x, Integer y) -> {
            System.out.println("函数式接口");
            return x + y;
        };

        // 如果lambda体返回值只有一个,则{}和return都可以省略,参数类型可省略
        Comparator<Integer> comparator1 = (x,y) -> x + y;

        // 如果只有一个参数()和类型可以省略
        Consumer<String> consumer1 =  str -> System.out.println(str);

    }

3、方法引用和构造器引用

3.1、方法引用

定义:方法引用就是通过方法的名字来指向一个方法。需满足实现接口的抽象方法的列表参数和返回值类型必须与方法应用的方法的参数列表和返回值类型保持一致。

使用:使用操作符 :: 将类(或对象)与方法名分隔开.

对象::实例方法名 类::静态方法名 类::实例方法名

例:Consumer<String> con = (x) -> System.out.println(x); 等同于: Consumer<String> con2 = System.out::println; 例:BiPredicate<String,String> bp = (x,y) ->x.equals(y); 等同于:BiPredicate<String,String> bp1 = String::equals; 注意:当函数式接口方法的第一个参数是需要引用方法的调用者,并且第二个参数是需要引用方法的参数(或无参数时)。可以使用ClassName::methodName

3.2、构造器引用

定义: 要求构造器参数列表和接口中抽象方法的参数列表一致。且方法的返回值即为构造器对应类的对象。

使用:ClassName::new

例:Function<Integer,MyClass> fun = (n) ->new MyClass(n); 等同于:Function<Integer,MyClass> fun = MyClass::new;
经验分享 程序员 微信小程序 职场和发展