Java函数式编程:Lambda表达式和函数式接口

Lambda表达式

Java的Lambda表达式形式为:

(params) -> { statements };

其中:

  1. 若params只有1个,可以省略():param -> { statements };
  2. 若params为0个,用()表示无参数:() -> { statements };
  3. 若代码为一行,则可省略{},无论该行代码是否为表达式:(params) -> expression;(params) -> statement;

函数式接口

Lambda表达式本质上是一个对象。而对象就必然有其对应的类型,就像一个字符串其类型为String一样。
当一个函数,其参数需要传入一个Lambda表达式时,函数的参数就需要明确定义该Lambda表达式的类型。
实际上,Java的Lambda表达式都是归属于某个具体已定义的类型的。根据Lambda表达式的参数与返回值数量和类型,Java定义了一组interface来接收Lambda表达式,称之为函数式接口

函数式接口有以下条件:

  1. 是一个interface。
  2. 有且仅有一个抽象方法。

另外:

  • interface默认继承Java.lang.Object,故Object的抽象方法不包含在内。
  • 可以使用@FunctionalInterface注解来标记函数式接口,有助于编译器进行检查。但@FunctionalInterface注解并非必须,只要满足条件,即使没有@FunctionalInterface注解编译器也会将接口识别为函数式接口。

例如:

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

Java8以后,Runnable接口多了@FunctionalInterface注解。这表示Runnable接口成为函数式接口了,可以接收Lambda表达式。
而实际上,由于Runnable接口有且仅有一个抽象方法,满足函数式接口的条件,所以即使不加@FunctionalInterface注解也依然会被识别为函数式接口。
所以可以自定义函数式接口:

@FunctionalInterface
public interface MyInterface {
    // 定义唯一的抽象方法
    void doWork();
    // toString()属于Object,不包含
    String toString();
}

使用:

MyInterface myInterface = () -> System.out.println("do work");

或将其作为参数类型:

class MyClass {
  public void doMyWork(MyInterface myInterface) {
    myInterface.doWork();
  }
}

MyClass myClass = new MyClass();
myClass.doMyWork(() -> System.out.println("do work"));

前面提到的Runnable接口同理。
除了Runnable接口,Java8还提供了一组函数式接口:

接口参数返回类型描述
PredicateTboolean判断一个对象是否符合条件。常用于对象过滤。
Function<T, R>TR将一个对象转换为另一个对象。
SupplierNoneT提供一个对象。生产者-消费者中的生产者。
ConsumerTvoid消费一个对象。生产者-消费者中的消费者。无返回值。
UnaryOperatorTT接收对象并返回同类型的对象。
BinaryOperator(T, T)T接收两个对象,并返回一个原对象。这三个对象的类型都相同。

其中:

  1. Supplier是唯一无参数的函数。其他函数都必须传入参数。
  2. Consumer是唯一无返回的函数。其他函数都会返回一个对象。

Runnable接口则是无参数,无返回值的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值