JDK8系列之使用Function函数式接口

news2024/11/16 18:54:04

一、函数式接口是jdk8的新特性之一,函数式接口是只包含一个抽象方法声明的接口。按分类主要分为四大接口类型: Function、Consumer、Predicate、Supplier。

接口参数返回值说明
Supplier<T>T供给型,无参,返回一个指定泛型的对象
Consumer<T>T消费型,传入一个指定泛型的参数,无返回值
Predicate<T>TBoolean断言型,判断函数,返回true或者false
Function<T,R>TR方法型,输入一个参数,返回一个结果

也可以直接去java.util.function包里面看,jdk提供了很多函数式接口。比如

序号函数式接口描述说明
1BiConsumer<T,U>代表了一个接受两个输入参数的操作,并且不返回任何结果
2BiFunction<T,U,R>代表了一个接受两个输入参数的方法,并且返回一个结果

二、实战:用函数式接口实现回调

员工执行业务逻辑完成任务后,老板收到回调通知。

1.Employee员工类

/**
 * 员工类
 *
 * @author zsh
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee<T, C> {
    /**
     * 员工的名字
     */
    private String name;
    /**
     * 员工处理任务的逻辑
     */
    private Function<T, C> taskFunction;

    /**
     * 处理任务的方法
     *
     * @param boss 发布任务的老板对象,包含老板名称,任务及回调
     */
    protected void doTask(Boss<T, C> boss) {
        if (null == boss || null == boss.getTask()) {
            throw new IllegalArgumentException("boss is not ready...");
        }
        if (null == this.taskFunction) {
            throw new IllegalArgumentException("employee has no skills for task...");
        }
        //执行任务的实际方法
        C callback = taskFunction.apply(boss.getTask());
        //将结果发送给老板
        boss.callback(this, callback);
    }
}

2.Boss老板类

/**
 * 老板类
 *
 * @author zsh
 */

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Boss<T, C> {
    /**
     * 老板的名字
     */
    private String name;
    /**
     * 老板待发布的任务
     */
    private T task;
    /**
     * 老板处理回调的方法
     */
    private BiConsumer<Employee<T, C>, C> callbackConsumer;

    /**
     * 指定员工去完成老板的任务
     * 员工完成任务后回调老板的接口
     *
     * @param employee 指定的员工
     */
    public void assignTask(Employee<T, C> employee) {
        employee.doTask(this);
    }

    /**
     * 完成任务后的回调
     *
     * @param employee
     * @param callback
     */
    protected void callback(Employee<T, C> employee, C callback) {
        if (null != callback && null != callbackConsumer) {
            callbackConsumer.accept(employee, callback);
        }
    }
}

3.CallBackService回调service

/**
 * 回调service
 *
 * @author zsh
 */
@Service
public class CallBackService {
    /**
     * 回调方法
     */
    public <T, C> void bossAssignTask() {
        //初始化老板对象,指定名称,任务和处理回调的逻辑
        Boss<T, C> bossA = new Boss<>(
                "bossA",
                (T) "a任务",
                (e, c) -> System.out.println("BossA收到" + e.getName() + "的回调啦..." + c.toString())
        );
        //初始化员工对象,指定名称和处理任务的逻辑
        Employee<T, C> employee = new Employee<>(
                "employee",
                t -> {
                    System.out.println("【员工A】收到任务" + t.toString() + "啦...");
                    try {
                        //通过睡眠,模拟执行任务
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("【员工A】完成任务" + t.toString() + "啦...");
                    return (C) "确认了处理结果";
                });
        //老板给员工安排任务,员工完成任务后老板会收到回调
        bossA.assignTask(employee);
        //员工可以换一个处理这个任务的逻辑
        employee.setTaskFunction(t -> {
            System.out.println("【员工A新逻辑】收到任务" + t.toString() + "啦...");
            try {
                //通过睡眠,模拟执行任务
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("【员工A新逻辑】完成任务" + t.toString() + "啦...");
            return (C) "确认了新逻辑处理结果";
        });
        //老板继续给员工安排任务
        bossA.assignTask(employee);
        //老板有了新任务
        bossA.setTask((T) "b任务");
        //老板继续给员工安排任务
        bossA.assignTask(employee);
        //老板有新的回调逻辑
        bossA.setCallbackConsumer((e, c) -> System.out.println("BossA新的回调方法收到" + e.getName() + "的回调啦..." + c.toString()));
        //老板继续给员工安排任务
        //bossA.assignTask(employee);
    }
}

4.CallBackController回调controller

/**
 * 回调Controller
 *
 * @author zsh
 */
@RestController
@RequestMapping("/callBackController")
public class CallBackController {
    @Autowired
    private CallBackService callBackService;

    @RequestMapping("/callBackBossAssignTask")
    public boolean callBackBossAssignTask() {
        callBackService.bossAssignTask();
        return true;
    }

}

5.测试结果

在这里插入图片描述
在这里插入图片描述

6.代码结构及下载地址

在这里插入图片描述
项目源码下载 spring-boot2.-xlearn 欢迎Star

参考资料
JDK8系列之使用Function函数式接口实现回调
java8 函数式接口 实现回调

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/96832.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计解谜游戏的30堂课

设计解谜游戏的30堂课 文章目录1.什么是Eureka Moment&#xff1f;2.谜题与幽默是同构的3.最大限度提高Sparkle4.避免无意义的谜题5.惊喜是Sparkle的重要源泉6.有趣的事实是惊喜的源泉7.尤里卡时刻并不是自豪8.不同解密者所寻求的解密体验是不尽相同的9.尤里卡是可以分享的10.创…

OVS-DPDK

要使用 ovs-dpdk&#xff0c;需要在node上构建 DPDK 并使用相应的 DPDK flag重新构建 ovs。 OVS-DPDK需要从源码编译&#xff0c;因为高度依赖内核等所在机器的环境&#xff0c;并需要配置很多参数以达到高性能。这意味着很难提供一个ovs-dpdk docker镜像来满足所有情况。OVS-D…

推荐系统学习笔记-基于图的模型

由来 基于图的模型&#xff08; graph-based model &#xff09;是推荐系统中的重要内容。其实&#xff0c;很多研究人员把基于邻域的模型也称为基于图的模型&#xff0c;因为可以把基于邻域的模型看做基于图的模型的简单形式。 在研究基于图的模型之前&#xff0c;首先需要将…

毫米波传感器原理介绍:角度估计

前边两篇博文从距离和速度两个维度进行了介绍&#xff0c;本篇将沿着第三个维度&#xff0c;角度进行分析&#xff0c;这也是毫米波传感器原理介绍的最后一篇理论基础。还是老规矩&#xff0c;我们先把公式列出来。 假设雷达两个接收天线之间的距离为d&#xff0c;θ 是物体相…

IS-95前向链路系统误码率matlab仿真,包括扩频调制,匹配滤波,RAKE接收

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 前向链路指由基站发往移动台的无线通信链路&#xff0c;也称作下行链路。IS-95系统前向链路最多可以有64个同时传输的信道&#xff0c;它们是在PN序列上再采用正交的Walsh码进行区分的信道&#…

网上书店系统/书店管理系统的设计与实现

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&…

C51 ——433M 射频信号控制喇叭

遥控按下后信号怎么被接受接 接收后的表现 &#xff1a; 厂商会告诉我们 这款告诉我们 接收模块对应针脚输出高电平 。 遥控控制喇叭 #include "reg52.h" sbit switcher P1^1; // 把继电器IN口 接到 P1.1 sbit D0_ON P1^2; // 把433M 射频信号接收器D0 口 接到P1.…

postman上传文件(multipart/form-data请求)

postman上传文件&#xff08;multipart/form-data请求&#xff09; 背景 网页的form表单中&#xff0c;如果存在上传文件的表单&#xff0c;则需要将form标签设置enctype"multipart/form-data"属性&#xff0c;意思是将Content-Type设置成multipart/form-data。 那…

今日小惊喜

今日限定小惊喜&#xff0c;一抬头突然发现有花开。

ESP32基础应用之lvgl显示中文

文章目录1 工程简介2 工程实现2.1 制作字库2.2 为字库自作分区表2.3 将字库移植到lvgl工程中2.4 将字库myFont.bin烧录到分区表中2.5 编写程序测试3 存在问题1 工程简介 该工程在《ESP32基础应用之LVGL基础》之上实现中文的显示。 参考文章 《ESP32 IDF LVGL8.0 flash 外部字…

CSC7720

CSC7720是一款用于5V2.1A开关电源的高效率同步整流控制IC。其具备较高的集成度&#xff0c;在有效的提升开关电源的转换效率的同时&#xff0c;减少了外围元器件的应用。CSC7720可用于DCM/QR开关电源系统。CSC7720内置45V的功率管&#xff0c;在系统中替代次级肖特基管,并提高整…

启动单文件组件项目及项目文件解释

启动项目文件&#xff1a;“package.json”&#xff1a; “package.json”&#xff1a;这个文件能记录当前项目中安装的所有模块&#xff0c;里面也有脚本&#xff0c;这个脚本可以快速启动我们的项目。 打开文件&#xff0c;可以看到“serve”&#xff0c;serve就是启动文件…

李沐精读论文:transformer 《Attention Is All You Need》 by Google

论文&#xff1a;Attention Is All You Need 视频&#xff1a;Transformer论文逐段精读【论文精读】_哔哩哔哩_bilibili 课程&#xff08;推荐先看这个&#xff09;&#xff1a;李宏毅机器学习&#xff1a;self-attention&#xff08;自注意力机制&#xff09;和transformer及其…

SpringBoot整合Shiro环境搭建

SpringBoot整合Shiro环境搭建导入 SpringBoot 和 Shiro 整合包的依赖&#xff1a; <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring --> <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring<…

XXL-Job分布式任务调度框架-- 定时任务注册案例2

一 案例操作 1.1 新建工程 简单建一个springboot的工程&#xff0c;如下图结构 1.2 工程的配置 1.pom中依赖配置 2&#xff09;代码 <!-- xxl-job --><dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactI…

ANTLR4入门(一):Windows安装antlr4命令行环境

最近开始学习ANTLR4&#xff0c;《ANTLR 4权威指南》这本书是看完了&#xff0c;现在开始实践&#xff0c;本系列文记录实践过程中的遇到的问题解决过程及心得体会 下载 从antlr官方网站下载最新的antr4版本(jar)&#xff1a;https://www.antlr.org/download.html 目前最新的…

牛客java刷题知识点总结(七)

instanceof运算符作用 instance是java的二元运算符&#xff0c;用来判断他左边的对象是否为右面类&#xff08;接口&#xff0c;抽象类&#xff0c;父类&#xff09;的实例。 我们考虑的时候&#xff0c;左边的对象如果是父类的引用指向子类的对象&#xff0c;我们用子类对象的…

C++【并查集】

文章目录一、并查集是什么并查集的简单表示并查集的合并并查集的代码实现并查集小练习1并查集小练习2并查集的压缩问题一、并查集是什么 并查集是一个森林 在一些应用问题中&#xff0c;需要将n个不同的元素划分成一些不相交的集合。开始时&#xff0c;每个元素自成一个单元素…

CS61A Lab 4

更好的阅读体验 Lab 4: Recursion, Tree Recursion lab04.zip What Would Python Do? Q1: Squared Virahanka Fibonacci Use Ok to test your knowledge with the following “What Would Python Display?” questions: python3 ok -q squared-virfib-wwpd -u✂️Hint: If…

CountDownLatch类的使用

&#x1f388;专栏链接:多线程相关知识详解 目录 一.CountDownLatch的介绍 二.CountDownLatch类里面的方法 三.CountDownLatch的两种应用场景 ①一等多情况 ②多等一情况 一.CountDownLatch的介绍 CountDownLatch是一种用来控制多线程的工具类,它被称为门阀、计数器或者…