Lambda表达式全解析

前言

在学习Lambda表达式前,先浇一盆冷水

Lambda不是什么特别神奇的东西,JDK8之前做不到的功能,添加了Lambda表达式还是做不到。

Lambda更多的是一种表达方式上的演进,使得我们用更简洁、精炼、表意的语言来编写代码。

少了匿名类的模式化代码。

image-20190423131722000

函数式接口

所谓函数式接口,就是只有一个抽象方法的接口

所有,也只有函数式接口出现的地方,才能够使用Lambda表达式

为什么呢?这个也很好理解,因为Lambda本质上是匿名类的一种简单表现形式,其是一段逻辑的实现

如果出现了多个抽象方法,那么一个Lambda是没办法表示多个逻辑的

接口中可以有默认实现;一个接口,如果有多个默认实现,一个抽象方法,也认为是函数式接口

函数描述符

函数式接口的抽象方法的签名基本上就是Lambda表达式的签名

例如,Runnable接口可以看作一个什么也不接受什么也不返回(void)的函数的
签名,因为它只有一个叫作run的抽象方法,这个方法什么也不接受,什么也不返回(void)

() -> void,代表了参数列表为空,且返回void的函数。这正是Runnable接口所代表的

总之,所谓函数描述符,就是描述了这个函数的请求参数与返回结果类型

@FunctionalInterface

如果是我们自定义的函数式接口,尽量加上这个注解

会执行编译器校验

即:如果我们的接口不符合函数式接口的定义,编译器就会报错

系统提供的函数式接口

Predicate

@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);

}

判断对象t是否符合要求

image-20190423141446678

Consumer

@FunctionalInterface
public interface Consumer<T> {

    void accept(T t);

}

处理对象t,比如可以打印这个对象等等

image-20190423141517831

image-20190423141530334

Function

@FunctionalInterface
public interface Function<T, R> {

    R apply(T t);


}

将对象t转化成对象r

image-20190423141418379

原始类型特化

PredicateConsumerFunction翻个函数式接口中,我们能够处理的数据类型都是引用类型,

如果我们要处理的就是intdouble等基本数据类型该怎么办?

如果我们使用基本数据类型的包装类,也是能够做到的,但是消耗的资源成本过高。

因此,JDK8提供了一组特殊的类,专门处理基本数据类型的函数式接口

image-20190423142241447

image-20190423142254509

方法引用

方法引用可以让我们重复使用方法的定义

image-20190423145214263

方法引用,是特定方法的Lambda表达式的一种快捷写法

它的基本思想是:如果一个Lambda表达式代表的只是”直接调用这个方法“,那最好还是用名称来调用吧

image-20190423145412491

三种方法引用

  • 指向静态方法的引用
  • 指向任意类型实例方法的引用
  • 指向现有对象实例方法的引用

image-20190423145947804

构造函数引用

对于一个有构造函数的类,我们可以用类名::new的方式来构造对象

image-20190423151356093

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值