0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

函数式接口的应用知识点

科技绿洲 来源:Java技术指北 作者:Java技术指北 2023-10-13 11:32 次阅读

概述

函数式接口将分为三个篇章来为大家介绍:

  • (应用篇一)(1)函数式接口的来源,(2)Lambda表达式,(3)双冒号运算符
  • (应用篇二)(4)详细介绍@FunctionInterface注解(5)对java.util.function包进行解读
  • (原理篇)介绍函数式接口的实现原理 应用篇将阶段相关的JDK源码以及给出典型的示例代码 原理篇则从编译、JVM维度来分析函数式接口的实现原理,具有一定深度,需要读者具备一定的底层知识。

说明:源码使用的版本为JDK-11.0.11

FunctionInterface

这一节,指北君给大家介绍如何声明一个函数式接口,FunctionInterface注解就是用于来干这件事情的,当我们为接口增加FunctionInterface注解后,编译器会按照函数式接口的约束进行检查。先看看注解的定义:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

源码显示该注解可用于类、接口和枚举类型,注解应用于运行时阶段。

如果仅从代码层面我们可能会犯错误,比如如下情况:

@FunctionalInterface
public interface IFuncInterfaceSample{
  void func1();
  void func2();
}

我们会发现编译器报错了,这是因为在设计FunctionInterface的时候还增加了额外的约束,这些约束无法在注解的定义中呈现,是通过编译器实现的,下面指北君就一一为小伙伴们道来。

首先、FunctionInterface是SAM接口,什么是SAM接口呢?全称Single Abstract Method,从英文字义我们就能明白,接口中只能有一个抽象方法。由于Java在接口中增加了对默认方法和静态方法的支持,因此采用SAM设计的接口也可以定义默认方法和静态方法,也就是说我们在使用了FunctionInterface注解的接口中还能够定义默认方法和静态方法。除了默认方法和静态方法外,这里还有一种列外,我们查看java.util.Comparator源码

@FunctionalInterface
public interface Comparator< T > {
    int compare(T o1, T o2);
    boolean equals(Object obj);
    ...

咦,这怎么回事,不是说只能有一个抽象方法么?小伙伴们仔细观察接口会发现其中一个是equals接口,这不是Object中的方法么?是的,这就是另一条特殊的约束,如果抽象方法是覆盖的是Object的方法,则不计入抽象方法的个数。

除了抽象方法的个数限制外FunctionInterface只能用于interface,不能用于class和enum,对于这种情形编译器也会报错。

小伙伴们有没想过FunctionInterface为什么要有上面提到的约束呢?相信有些已经隐隐感觉到了:Java是通过类来实现函数式编程的(这部分内容将在原理篇中说明)。

最后,还有一个重点知识:是不是只有使用了@FunctionalInterface才能作为函数式接口呢?相信有不少伙伴和指北君之前一样理所当然地觉得显然应该是这样嘛。但是,JDK的世界很精妙:只要符合函数式接口约束条件的接口,即使没有采用@FunctionalInterface,编译器都会处理成函数式接口,比如下面的示例代码:

public interface IFuncInterfaceWithoutAn {
  boolean test(int i);
}

public class Demo {
  public static void main(String args[]) {
    IFuncInterfaceWithoutAn whithout = (x)- >x%2==1;
    System.out.println(whithout.test(3));
  }
}

java.util.function

之前的学习,指北君介绍了什么是函数式编程,如果写一段Lambda表达式,以及学习如何申明函数式接口。本节我们将学习JDK为我们提供的基础函数式接口,这些接口位于java.util.function包中,它们可以满足我们很多通用场景的使用需要。

图片
function包

打开java.util.function包,我们发现里面足足有43个接口,这43个接口就是JDK提供给我们43把剑,如果要让小伙伴舞动这43把剑,是不是感觉鸭梨山大了呢?小伙伴们,别慌!在你看完指北君后面的分析后,你就可以将这43把剑化为无形,做到手中无剑心中有剑。

指北君先带领小伙伴们对接口名称进行分析。是的,是接口名称,不是源码

图片
接口名称解析

从思维导图中可以看到,接口的主体为最后的单词,包含:Consumer,Function,Predicate,Supplier,Operator。

图片
接口主体类别

除了主体外,小伙伴是不是还看到了Unary,Binary,Bi这种表示参数个数的修饰词。

修饰词作用
Unary一元
Binary二元
BiBinary缩写

再就剩下参数类型和方向的修饰词和参数方向Int,Long,Double,Obj,(X)To(Y)。

通过以上解析,我们可以确定所有的接口都是用于描述函数的输入参数和返回,这就是java.util.function留在我们心中终极大剑。有了这把终极武器,我们可以对于这43把剑信手拈来,也随意创造自己的武器,当然,要创造新的武器,按照这43把剑依葫芦画瓢是可以,但是要打造精品武器还需要掌握我们接下来介绍的FunctionInterface接口了。

在对整个java.util.function包了然于胸后,我们再打开一个典型的接口看看源码。function包中的类型都为接口类型,并且使用了@FunctionInterface注解,且每个接口都且只有一个接口(抽象)方法,部分接口存在默认方法和静态方法。

@FunctionalInterface
public interface Consumer< T > {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

    /**
     * Returns a composed {@code Consumer} that performs, in sequence, this
     * operation followed by the {@code after} operation. If performing either
     * operation throws an exception, it is relayed to the caller of the
     * composed operation.  If performing this operation throws an exception,
     * the {@code after} operation will not be performed.
     *
     * @param after the operation to perform after this operation
     * @return a composed {@code Consumer} that performs in sequence this
     * operation followed by the {@code after} operation
     * @throws NullPointerException if {@code after} is null
     */
    default Consumer< T > andThen(Consumer< ? super T > after) {
        Objects.requireNonNull(after);
        return (T t) - > { accept(t); after.accept(t); };
    }
}

accept为核心接口方法,andThen为方便复杂组合场景提供的默认方法。function包的整个代码逻辑都很简洁易懂,部分Operator继承了Function,指北君就不一一赘述了。

小结

至此,函数式接口的应用知识点已经介绍和分析完,涵盖知识点包含:java.util.function包,FunctionInterface注解,Lambda表达式,双冒号操作符等知识点。函数式接口在集合,流中应用较为广泛,也证明了其在数据时候的显著优势,各位小伙伴可以结合这些JDK中的源码进行巩固加深。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    8575

    浏览量

    151015
  • 源码
    +关注

    关注

    8

    文章

    639

    浏览量

    29185
  • 函数
    +关注

    关注

    3

    文章

    4327

    浏览量

    62571
  • 代码
    +关注

    关注

    30

    文章

    4779

    浏览量

    68522
  • JDK
    JDK
    +关注

    关注

    0

    文章

    81

    浏览量

    16592
收藏 人收藏

    评论

    相关推荐

    嵌入C语言知识点总结

    怎么才能做好嵌入开发?学好C语言吧!今天就来推荐一篇大佬写的嵌入C语言知识点总结。
    发表于 09-27 09:53 1172次阅读

    嵌入内存管理的知识点总结

    任何程序运行起来都需要分配内存空间存放该进程的资源信息的,C程序也不例外。C程序中的变量、常量、函数、代码等等的信息所存放的区域都有所不同,不同的区域又有不同的特性。C语言学习者、尤其是在学习嵌入的朋友,这些知识点一定要吃透!
    发表于 08-17 09:33 497次阅读
    嵌入<b class='flag-5'>式</b>内存管理的<b class='flag-5'>知识点</b>总结

    嵌入C/单片机C/标准C知识点

    :嵌入C、标准C、单片机C区别  知识点2:程序组成和程序原则  知识点3:变量类型(函数、数组、指针、结构体等类型)  知识点4:常用的
    发表于 10-24 14:42

    工程师总结了一些C语言的知识点

    仅供大家参考,想一起和我讨论吗,可以加一下我的QQ2685896890,黄老师一、嵌入C/单片机C/标准C知识点知识点1:嵌入C、标准C、单片机C区别知识点2:程序组成和程序原则
    发表于 07-25 10:23

    【信盈达】C语言知识点的总结

    一、嵌入C/单片机C/标准C知识点知识点1:嵌入C、标准C、单片机C区别知识点2:程序组成和程序原则知识点3:变量类型(
    发表于 10-08 14:41

    STM32外部中断知识点概述

    STM32外部中断概述知识点(1)知识点(2)知识点(3)中断服务函数外部中断常用库函数外部中断的一般配置步骤
    发表于 08-16 07:43

    C语言程序小知识点总结

    C语言总结(stm32嵌入开发)文章目录C语言总结(stm32嵌入开发)c程序小知识点总结1.静态变量static与外部变量extern的使用2.函数封装后返回值的方法3.软件寄存
    发表于 11-05 07:45

    RK3399 HDMI接口知识点汇总,绝对实用

    RK3399 HDMI接口知识点汇总,绝对实用
    发表于 03-07 06:53

    高一数学知识点总结

    高一数学知识点总结高一数学知识点总结高一数学知识点总结
    发表于 02-23 15:27 0次下载

    液晶屏知识点培训

    液晶屏知识点液晶屏分辨率等,液晶屏接口
    发表于 01-01 08:00 42次下载

    PWM知识点详解

    PWM知识点
    发表于 03-16 08:00 44次下载

    嵌入知识点总结

    嵌入知识点总结(arm嵌入开发led过程)-嵌入知识点总结                    
    发表于 07-30 14:20 23次下载
    嵌入<b class='flag-5'>式</b><b class='flag-5'>知识点</b>总结

    数字电路知识点总结

    本文整理了数字电路课程中的相关基本的知识点和较为重要的知识点,用于求职的数电部分的知识准备,差缺补漏。
    的头像 发表于 05-30 15:07 4838次阅读
    数字电路<b class='flag-5'>知识点</b>总结

    什么是函数接口

    、及其所使用的一些和函数接口相关的知识点进行一个全面的学习。函数
    的头像 发表于 10-13 14:48 1508次阅读
    什么是<b class='flag-5'>函数</b><b class='flag-5'>式</b><b class='flag-5'>接口</b>

    接口测试理论、疑问收录与扩展相关知识点

    本文章使用王者荣耀游戏接口、企业微信接口的展示结合理论知识,讲解什么是接口测试、接口测试理论、疑问收录与扩展相关
    的头像 发表于 11-15 09:12 308次阅读
    <b class='flag-5'>接口</b>测试理论、疑问收录与扩展相关<b class='flag-5'>知识点</b>