runnable、callable、consumer、supplier

news2024/12/27 13:45:07

Java 没有委托的概念; 相反,如果需要一个指向函数的指针,可以创建内联匿名类(或 Java 8 的 lambda 表达式),它们是为此建议设计的某些接口的实现(也称为 Java 8 的功能接口)。 然而,随着 Java 的发展,越来越多的此类接口被添加进来。 虽然它们看起来非常相似且令人困惑,但它们中的每一个都有一个独特的特征,使其与众不同。 可以将它们中的许多映射到 .NET 中的相同类型。 下表列出了一些著名的接口,但还有更多。 例如,为了支持带有两个参数的函数,Java 有另一个接口称为 BiFunction,如果您需要更多参数,则必须创建自己的接口。 请记住,如果唯一的区别是类型参数的数量,Java(最高版本 10)不支持相同的类名。 (在 .NET 中有各种 Func 和 Action 类型,最多有 16 个类型参数。)
在这里插入图片描述
Supplier () -> x
Consumer x -> ()
Callable () -> x throws ex
Runnable () -> ()
Function x -> y


Runnable


Since Java’s early days, multithreading has been a major aspect of the
language. Runnable is the core interface provided for representing
multithreaded tasks, and Java 1.5 provided Callable as an improved
version of Runnable.

Runnable 接口是一个函数式接口,有一个不接受任何参数或返回任何值的 run() 方法。
这适用于我们不寻找线程执行结果的情况,例如传入事件日志记录:

public interface Runnable {
    public void run();
}
public class EventLoggingTask implements  Runnable{
    private Logger logger
      = LoggerFactory.getLogger(EventLoggingTask.class);

    @Override
    public void run() {
        logger.info("Message");
    }
}

在此示例中,线程将仅从队列中读取消息并将其记录在日志文件中。任务没有返回任何值。 我们可以使用 ExecutorService 启动任务:

public void executeTask() {
    executorService = Executors.newSingleThreadExecutor();
    Future future = executorService.submit(new EventLoggingTask());
    executorService.shutdown();
}

Callable


Callable 接口是一个通用接口,包含一个返回通用值 V 的 call() 方法:

public interface Callable<V> {
    V call() throws Exception;
}
public class FactorialTask implements Callable<Integer> {
    int number;

    // standard constructors

    public Integer call() throws InvalidParamaterException {
        int fact = 1;
        // ...
        for(int count = number; count > 1; count--) {
            fact = fact * count;
        }

        return fact;
    }
}
@Test
public void whenTaskSubmitted_ThenFutureResultObtained(){
    FactorialTask task = new FactorialTask(5);
    Future<Integer> future = executorService.submit(task);
 
    assertEquals(120, future.get().intValue());
}

Consumer


从字面意思上我们就可以看得出,consumer接口就是一个消费型的接口,通过传入参数,然后输出值
我们下面就先看一个例子

@Test
public void test_Consumer() {
    //① 使用consumer接口实现方法
    Consumer<String> consumer = new Consumer<String>() {

        @Override
        public void accept(String s) {
            System.out.println(s);
        }
    };
    Stream<String> stream = Stream.of("aaa", "bbb", "ddd", "ccc", "fff");
    stream.forEach(consumer);

    System.out.println("********************");

    //② 使用lambda表达式,forEach方法需要的就是一个Consumer接口
    stream = Stream.of("aaa", "bbb", "ddd", "ccc", "fff");
    Consumer<String> consumer1 = (s) -> System.out.println(s);//lambda表达式返回的就是一个Consumer接口
    stream.forEach(consumer1);
    //更直接的方式
    //stream.forEach((s) -> System.out.println(s));
    System.out.println("********************");

    //③ 使用方法引用,方法引用也是一个consumer
    stream = Stream.of("aaa", "bbb", "ddd", "ccc", "fff");
    Consumer consumer2 = System.out::println;
    stream.forEach(consumer);
    //更直接的方式
    //stream.forEach(System.out::println);
}

lambda 表达式作为 consumer

Consumer<String> consumer1 = (s) -> System.out.println(s);

方法引用作为 consumer

Consumer consumer2 = System.out::println;

Supplier


Supplier 接口是一个供给型的接口,其实,说白了就是一个容器,可以用来存储数据,然后可以供其他方法使用的这么一个接口。

@Test
public void test_Supplier() {
    //① 使用Supplier接口实现方法,只有一个get方法,无参数,返回一个值
    Supplier<Integer> supplier = new Supplier<Integer>() {
        @Override
        public Integer get() {
            //返回一个随机值
            return new Random().nextInt();
        }
    };

    System.out.println(supplier.get());

    System.out.println("********************");

    //② 使用lambda表达式,
    supplier = () -> new Random().nextInt();
    System.out.println(supplier.get());
    System.out.println("********************");

    //③ 使用方法引用
    Supplier<Double> supplier2 = Math::random;
    System.out.println(supplier2.get());
}

看一下这段代码,我们通过创建一个 Supplier 对象,实现了一个 get 方法,这个方法无参数,返回一个值;所以,每次使用这个接口的时候都会返回一个值,并且保存在这个接口中,所以说是一个容器。

Supplier<Integer> supplier = new Supplier<Integer>() {
            @Override
            public Integer get() {
                //返回一个随机值
                return new Random().nextInt();
            }
        };
Supplier<Double> supplier2 = Math::random;
System.out.println(supplier2.get());

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

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

相关文章

Java项目:SSM汽车维修中心管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本系统包括普通用户和管理员两种角色&#xff1b; 用户角色包含以下功能&#xff1a; 用户信息管理,查看车辆信息,维修记录查看等功能。 管理…

ORB-SLAM2 --- Tracking::GrabImageMonocular函数解析

目录 1.函数作用 2.到这步之前我们做了什么 3.code 4.函数解析 1.函数作用 哈哈哈&#xff0c;这其实应该是这个专栏的第一篇文章&#xff0c;也没什么必要写&#xff0c;但是我怕大家看的时候对单目还没有初始化没有进入跟踪线程前面比较懵逼&#xff0c;所以我补了此内…

Kali Linux安装go语言环境详解

今天继续给大家介绍渗透测试相关知识&#xff0c;本文主要内容是Kali Linux安装go语言环境。 免责声明&#xff1a; 本文所介绍的内容仅做学习交流使用&#xff0c;严禁利用文中技术进行非法行为&#xff0c;否则造成一切严重后果自负&#xff01; 再次强调&#xff1a;严禁对未…

【实操篇】Linux权限管理

目录 ●权限的基本介绍 ●rwx权限 ①rwx作用到文件 ②rwx作用到目录 ●修改权限——chmod ①、-、变更权限 ②数字变更权限 ●修改文件所有者——chown ●修改文件所在组——chgrp ●权限的基本介绍 从中随便找一行进行分析如下图所示&#xff1a; 1.文件类型 - &#x…

Hudi 0.12.0 搭建——集成 Hive3.1 与 Spark3.2

Hudi 搭建环境准备一、安装 Maven1.解压2.配置环境变量3.修改 Maven 下载源二、安装 Hudi1.解压2.配置环境变量3.修改 Hudi 下载源与对应版本号4.修改源码以兼容 Hadoop3.x5. 解决 Spark 依赖冲突6. 解决 Spark 向 Hudi 插入报错7. 编译 Hudi8. 启动测试集群其它生态安装与配置…

JSP ssh驾校管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 JSP ssh驾校管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式 开发。开发环境为TOMCAT7.0,Mye…

6秒钟读懂网络攻击和防御的有关产品理论

文章目录一 常见网络攻击1.病毒攻击2.DDos网络攻击3.木马攻击WebsSheLL4.渗透攻击数据拖取5.APP漏洞6.营销撸羊毛7&#xff0c;DDoS攻击挑战二&#xff0c;大禹基本功能1.基础防护2.BGP高防包3.BGP高仿IP4.棋牌盾三&#xff0c;大禹技术原理1.高仿IP牵引攻击流量&#xff0c;保…

Java安全--CC3

CC3和CC1和CC6的执行命令方式不一样。CC3使用的是动态类加载。我们把恶意代码写在加载类的静态构造方法中。需要注意的是&#xff1a; 当初始化的时候就会执行静态构造方法&#xff0c;defineClass的时候是不会执行静态构造代码块的&#xff0c;我们在找利用点的时候需要有new…

1658 页的《Java 面试突击核心讲》在牛客网火了,完整版 PDF 开放下载!

前言 我们都知道&#xff0c;在程序员的职业生涯中&#xff0c;有多个发展方向&#xff0c;不过就数据表明&#xff0c;近年来选择架构师方向的开发人员也越来越多。 对于架构师的发展前途&#xff0c;我相信是已经没有争议的&#xff0c;但这个“概念”对于很多开发人员来说…

[ vulhub漏洞复现篇 ] solr XML外部实体注入(CVE-2017-12629-xxe)

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

网站权重怎么批量查?怎么批量查询网站的360权重

批量查询网站360权重的操作&#xff1a; 第一步、打开SEO综合查询工具 第二步、添加需要查询的网站域名&#xff08;有多少放多少&#xff0c;一行一个域名&#xff09; 第三步、勾选360权重PC权重和360移动权重 第四步、点击开始查询 第五步、等待查询结果出来 如果需要导出查…

vue 前端实现随机背景色

目录前言&#xff1a;步骤&#xff1a;功能效果展示&#xff1a;代码&#xff1a;总结&#xff1a;前言&#xff1a; 要求是页面对应的几个模块每次打开都要显示多个不同的随机颜色&#xff0c;点击刷新则显示的颜色改变。我就封装成了一个函数&#xff0c;有不足的地方&#…

【小甲鱼C语言】课后笔记第一章第二节——变量

目录 1、变量的命名规则 2、关键字 3、基本数据类型 4、声明变量的语法 5、课后习题&#xff08;编程题&#xff09; 1、变量的命名规则 C语言变量名只能是英文字母&#xff08;A-Z&#xff0c;a-z&#xff09;和数字&#xff08;0-9&#xff09;或者下划线&#xff08;_&…

【云原生进阶之容器】第一章Docker核心技术1.1节——Docker综述

1 Docker简述 1.1 什么是Docker Docker是一个开源的软件项目,让用户程序部署在一个相对隔离的环境运行,借此在Linux操作系统上提供一层额外的抽象,以及操作系统层虚拟化的自动管理机制。需要额外指出的是,Docker并不等于容器(containers),Docker只是容器的一种,其他的种…

使用vite插件编写tsx文件

一般情况下&#xff0c;我们在template标签里去写静态页面模板。现在可以扩展另一种书写风格 tsx&#xff0c;类似react的jsx语法。vue2 的时候就已经支持jsx写法&#xff0c;只不过不是很友好&#xff0c;随着vue3对typescript的支持度增高&#xff0c;tsx写法越来越被接受。 …

基本素质提升(一)----日常/命令积累

目录 一、引言 二、日常积累 三、命令积累 一、引言 这个主题主要带大家学习一下日常开发所使用的命令及相关知识&#xff0c;会持续更新 二、日常积累 1、kill 给某个进程发送信号 kill -STOP pid(进程号)&#xff0c;可以发送任何信号给进程&#xff1b;kill -STOP %…

【云计算与大数据技术】云计算概论介绍

一、什么是云计算 云计算&#xff08;cloud computing&#xff09;是基于互联网的相关服务的增加、使用和交付模式&#xff0c;通常涉及通过互联网来提供动态易扩展且经常是虚拟化的资源。云是网络、互联网的一种比喻说法&#xff0c;过去往往用来用云表示电信网&#xff0c;后…

基于51单片机电动自行车车速报警系统proteus仿真原理图程序

功能&#xff1a; 0.本项目采用STC89C52作为单片机系统的控制MCU 1.LCD1602液晶分三种显示模式 a)显示实时速度和本次里程 b)显示当前时间 c)显示报警速度和总里程 2.超过报警速度将声光报警 3.功能按键介绍 a显示状态下: 上’键——电机速度1 下’键——电机速度-1 设置’键—…

Java基于JSP+mysql的学科竞赛管理系统

随着我学科竞赛是对课堂上所学的理论知识的实践运用&#xff0c;是考察大学生学科基本理论知识和解决实际问题能力的比赛&#xff0c;是高等学校人才培养质量的标志之一&#xff0c;是培养知识-能力-素质协调发展的创新型、高素质人才重要途径&#xff0c;对高校的学风、就业也…

Go开发中配置一个Logger日志的功能实现

为什么需要Logger 一般在开发项目的时候我们都是需要一个存储日志的文件&#xff0c;因为在部署项目以后&#xff0c;我们只能通过去筛查日志进行检索问题&#xff0c;这时候日志是否可以呈现清晰这个对于我们进行排查工作是十分重要的&#xff0c;所以Logger能否展示出我们最…