【Java函数篇】Java8中函数接口Function使用详解

文章目录

    • 函数接口Function
      • 函数式接口只允许有一个抽像方法
      • 通过Lambda表达式实现接口
    • @FunctionalInterface注解
      • 构建一个函数式接口
      • 使用自己创建的函数式接口
    • JDK中的函数式接口
      • Function函数
      • 最常用的Function<T,R>使用
        • apply(T t)
        • andThen(Function<? super R,? extends V> after)
        • compose(Function<? super V,? extends T> before)
      • 最常用的BiFunction<T, U, R>使用
        • apply(T t, U u)
        • andThen(Function<? super R,? extends V> after)
    • 在Stream流中的用法
    • 总结

函数接口Function

在Java 8 中引入了函数式接口(Functional Internal),函数式接口的特征是它是只有一个抽象方法的接口。

  • 是个接口
  • 只有一个抽象方法
    在这里插入图片描述

函数式接口只允许有一个抽像方法

函数式接口是 Java 8 中的新增功能。通常,函数式接口中的方法只能有一个抽象方法,这些函数式接口也称为单抽象方法接口。但是除了一个抽象方法之外,函数式接口还可以具有静态方法和继承自object的方法:

  • 默认方法(default methods),只能有一个
  • 静态方法(static methods),可以有多个
  • 继承自object 的public方法,可以有多个

通过Lambda表达式实现接口

在 Java 中,lambda 表达式可用于表示实现函数式接口的实例。例如,Comparator 接口就是一个函数式接口。

@FunctionalInterface
public interface Comparator<T> {
	int compare(T o1, T o2);
	// equals继承自object,所以并不违反函数接口单抽象方法的原则
	boolean equals(Object obj);

	// 其他都是default methods
}

虽然Comparator有两个抽象方法,但是其中equals继承自Object类,所以他并不算违反单抽象方法的原则。除了这两个抽象方法外,其他都是default method。所以Comparator就是一个函数式的接口 。

在Java中使用Lambda表达式实现Comparator接口:

//Compare by Id
Comparator<Employee> compareById = Comparator.comparing(e -> e.getId());
Comparator<Employee> compareByFirstName = Comparator.comparing(e -> e.getFirstName());

其中e -> e.getId() 和 e->e.getFirstName() 是个函数,Comparator.comparing()接受这个函数,返回的值是Comparator接口。
在这里插入图片描述

@FunctionalInterface注解

Java 8 引入了注释 @FunctionalInterface,用于将接口标记为函数式接口。此注释的主要用途是当接口违反一个抽象方法的契约时,产生编译器级错误。但是注意:该注解并不是必须的

如果接口有一个抽象方法并且没有 @FunctionalInterface 注解,那么该接口仍然是一个函数式接口,并且可以作为 lambda 表达式的目标类型。注释的存在用于防止我们无意中将函数接口更改为非函数接口,因为编译器会捕获它。

构建一个函数式接口

@FunctionalInterface
public interface MyFirstFunctionalInterface
{
    public void firstWork();
}

如果我们再添加一个抽象方法,可以看到错误提示。
在这里插入图片描述

使用自己创建的函数式接口

定义好函数接口,其中泛型T作为参数输入类型,R作为返回值类型限定:

@FunctionalInterface
public interface MySecondFunctionalInterface<T, R> {
    R doSomething(T name);
}

使用:

    @Test
    public void testSecondFunction() {
        MySecondFunctionalInterface<String, Integer> inputLength = String::length;
        MySecondFunctionalInterface<String, String> addGreeting = s -> "welcome " + s;
        MySecondFunctionalInterface<String, String> revertInput = StrUtil::reverse;


        System.out.println(inputLength.doSomething("hello world"));
        System.out.println(addGreeting.doSomething("sea"));
        System.out.println(revertInput.doSomething("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
		
		// 输出信息
		// 11
		// welcome sea
        // ZYXWVUTSRQPONMLKJIHGFEDCBA
    }

JDK中的函数式接口

在java中使用比较广泛的函数接口如下:

  • Function:仅包含apply()方法
  • Runnable:仅包含 run() 方法
  • Comparable:仅包含 compareTo () 方法。
  • ActionListener:仅包含 actionPerformed ()方法。
  • Callable:仅包含 call () 方法。
  • Predicate:一个接受一个参数并返回 true 或 false的布尔值函数。
  • BiPredicate:带有两个参数的谓词。
  • Consumer:一种接受一个参数、对其进行操作且不返回结果的操作。
  • BiConsumer:带有两个参数的消费者。
  • Supplier:一个返回值的供应者。 Function<T, R>:接受类型为 T的参数并返回类型为 R 的结果。
  • BiFunction<T, U, R>:接受类型为 T 和 U 的两个参数并返回类型为 R 的结果。

Function函数

序号接口描述
1Function<T, R>接收一个参数并返回结果的函数
2BiFunction<T,U.R>接受两个参数并返回结果的函数
3DoubleFunction接收一个 double 类型的参数并返回结果的函数
4DoubleToIntFunction接收一个 double 类型的参数并返回 int 结果的函数
5DoubleToLongFunction接收一个 double 类型的参数并返回 long 结果的函数
6IntFunction接收一个 int 类型的参数并返回结果的函数
7IntToDoubleFunction接收一个 int 类型的参数并返回 double 结果的函数
8IntToLongFunction接收一个 Int 类型的参数并返回 long 结果的函数
9LongFunction接收一个 long 类型的参数并返回结果的函数
10LongToDoubleFunction接收一个 long 类型的参数并返回 double 结果的函数
11LongToIntFunction接收一个 long 类型的参数并返回 int 结果的函数
12ToDoubleBiFunction<T,U>接收两个参数并返回 double 结果的函数
13ToDoubleFunction接收一个参数并返回 double 结果的函数
14ToIntBiFunction<T, U>接收两个参数并返回 int 结果的函数
15ToIntFunction接收一个参数并返回 Int 结果的函数
16ToLongBiFunction<T, U>接收两个参数并返回 long 结果的函数
17ToLongFunction接收一个参数并返回 long 结果的函数

最常用的Function<T,R>使用

在这里插入图片描述

apply(T t)
Function<String, String> function = a -> a + " Jack!";
System.out.println(function.apply("Hello")); // Hello Jack!
andThen(Function<? super R,? extends V> after)
Function<String, String> function = a -> a + " Jack!";
Function<String, String> function1 = a -> a + " Bob!";
String greet = function.andThen(function1).apply("Hello");
System.out.println(greet); // Hello Jack! Bob!
compose(Function<? super V,? extends T> before)
Function<String, String> function = a -> a + " Jack!";
Function<String, String> function1 = a -> a + " Bob!";
String greet = function.compose(function1).apply("Hello");
System.out.println(greet); // Hello Bob! Jack!

最常用的BiFunction<T, U, R>使用

与上面不同的是,这个可以传递两个参数
在这里插入图片描述

apply(T t, U u)
BiFunction<String, String, String> biFunction = (a, b) -> a + b;
System.out.println(biFunction.apply("Hello ", "Jack!")); // Hello Jack!
andThen(Function<? super R,? extends V> after)
BiFunction<String, String, String> biFunction = (a, b) -> a + b;
Function<String, String> function = (a) -> a + "!!!";
System.out.println(biFunction.andThen(function).apply("Hello", " Jack")); // Hello Jack!!!

在Stream流中的用法

Stream流中map接受一个Function参数如下:
在这里插入图片描述
代码:

    @Test
    public void testFunctionInStream() {
        List<PredicateDemo.People> people = new PredicateDemo().mockPeopleList();
        people.stream().map(x -> x.getName()).forEach(System.out::println);
    }

可以输出每个人的名字,亦或将每个名字组装成一个list:

    @Test
    public void testFunctionInStream() {
        List<PredicateDemo.People> people = new PredicateDemo().mockPeopleList();
        people.stream().map(x -> x.getName()).collect(Collectors.toList());
    }

还可以使用Comparator将用户按照名字进行排序,如下:

    @Test
    public void testFunctionInStream() {
        List<PredicateDemo.People> people = new PredicateDemo().mockPeopleList();
        people.stream().sorted((p1, p2) -> p1.getName().compareTo(p2.getName())).forEach(System.out::println);
    }

总结

以上介绍了如何在 Java 中创建和管理函数式接口。我们了解到函数式接口只有一个抽象方法,并且可以通过 lambda 表达式来实现。还分享了 JDK 提供的现有函数式接口,最后通过例子了解了如何创建和使用函数式接口。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CTF(五)

导言&#xff1a; 本文主要讲述在CTF竞赛中&#xff0c;web类题目easyphp。 靶场链接&#xff1a;攻防世界 (xctf.org.cn) 参考文章原文链接&#xff1a;Web安全攻防世界05 easyphp&#xff08;江苏工匠杯&#xff09;_攻防世界 easyphp-CSDN博客 一&#xff0c;观察页面。…

OpenCV学习笔记5——图像的数值计算

目录 一、简单数值计算 二、opencv中提供函数进行计算 三、cv2.addWeighted 一、简单数值计算 在opencv中&#xff0c;我们有许多可以获取图像各类数值的办法&#xff0c;许多函数能获得各种方面的数据。但如果我们什么都不用&#xff0c;仅仅对图像上每一个点做加法运算会…

计算机网络:数据链路层 —— 扩展共享式以太网

文章目录 共享式以太网共享式以太网存在的问题在物理层扩展以太网扩展站点与集线器之间的距离扩展共享式以太网的覆盖范围和站点数量 在链路层扩展以太网网桥的主要结构网桥的基本工作原理透明网桥自学习和转发帧生成树协议STP 共享式以太网 共享式以太网是当今局域网中广泛采…

【MySQL】表的约束、基本查询、内置函数

目录 1. 表的约束1.1 空属性1.2 默认值1.3 列描述1.4 zerofill1.5 主键1.6 自增长1.7 唯一键1.8 外键 2. 基本查询2.1 表的增删改查2.1.1 插入数据2.1.2 插入否则更新2.1.3 替换插入 2.2 Retrieve2.2.1 select ----- 查询2.2.2 where ----- 筛选2.2.3 order by ----- 结果排序2…

全方面熟悉Maven项目管理工具(一)认识Maven、Maven如何安装?

1. Maven 1.1 应用场景&#xff1a; 本地仓库&#xff1a; 我们使用的jar依赖于maven的本地仓库 自动部署&#xff1a; 本地仓库推送到远程仓库&#xff0c; 远程库通知 Jenkins工具&#xff0c;Jenkins 调用Maven构建war包&#xff0c;Jenkins 再调用准备好的脚本程序&…

linux jdk环境变量变量新配置方式

1.jdk17--> jdk8环境变量配置,source /etc/profile了也不生效 which java #假设上命令运行结果为/usr/bin/java rm -rf /usr/bin/javaln -s $JAVA_HOME/bin/java /usr/bin/java source /etc/profile# 断开本次远程连接&#xff0c;重连检查java -version 2.jdk环境变量变…

UDP和TCP的区别

UDP&#xff08;User Datagram Protocol&#xff09;和TCP&#xff08;Transmission Control Protocol&#xff09;是两种不同的传输层协议&#xff0c;它们在数据传输的方式和可靠性方面有显著区别&#xff1a; 连接方式&#xff1a; TCP&#xff1a;面向连接的协议&#xff0…

Unity DOTS中的Archetype与Chunk

Unity DOTS中的Archetype与Chunk 在Unity中&#xff0c;archetype&#xff08;原型&#xff09;用来表示一个world里具有相同component类型组合的entity。也就是说&#xff0c;相同component类型的entity在Unity内部会存储到一起&#xff0c;共享同一个archetype。 使用这样的设…

Linux系统:本机(物理主机)访问不了虚拟机中的apache服务问题的解决方案

学习目标&#xff1a; 提示&#xff1a;本文主要讲述-本机(物理主机)访问不了虚拟机中的apache服务情况下的解决方案 Linux系统&#xff1a;Ubuntu 23.04&#xff1b; 文中提到的“本机”&#xff1a;代表&#xff0c;宿主机&#xff0c;物理主机&#xff1b; 首先&#xff0c…

linux 中mysql my.cnf 配置模版

前置准备 sudo systemctl stop mysqld 注意&#xff1a; 原本配置重命名做备份 备份数据 删文件 直接新建 my.cnf 把配置 11要粘进去的内容 直接粘进去 注意&#xff1a;尽管log-bin 和 log_bin 都可以启用二进制日志&#xff0c;但为了保持与现代MySQL版本的兼容性和一…

物流行业创新:SpringBoot技术应用

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

24.安卓逆向-frida基础-objection工具3-实战

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要盲目相信。 工…

全方面熟悉Maven项目管理工具(五)教你IDEA创建Maven基本项目、导入工程和模块,并为你讲解Maven的生命周期

1. IDEA 配置 Maven 本身 IDEA 就可以在一个项目中创建多个子模块。 1.1 创建父工程 如果要构建不同的 Maven 工程类型&#xff0c;可以勾选【从原型创建】在列表中选择工程类型 1.2 IDEA 配置 Maven 本地仓库 在设置中前往&#xff1a;构建、执行、部署 >> 构建工具…

鸿蒙网络编程系列28-服务端证书锁定防范中间人攻击示例

1. TLS通讯中间人攻击及防范简介 TLS安全通讯的基础是基于对操作系统或者浏览器根证书的信任&#xff0c;如果CA证书签发机构被入侵&#xff0c;或者设备内置证书被篡改&#xff0c;都会导致TLS握手环节面临中间人攻击的风险。其实&#xff0c;这种风险被善意利用的情况还是很…

Linux基础项目开发day06:量产工具——业务系统

文章目录 前言一、流程代码框架1、业务系统框架流程2、主页面流程图3、main.c实现流程 二、处理配置文件1、配置文件是啥&#xff1f;config.h 2、怎么处理配置文件&#xff1f;config.c 三、生成界面1、计算每个按钮的Region2、逐个生成按钮画面->生成页面 四、读取输入事件…

记录一次hiveserver2卡死(假死)问题

问题描述 给开发人员开通了个账号&#xff0c;连接hive进行查询&#xff0c;后来发现&#xff0c;hive服务有时候会卡死&#xff0c;查询不了&#xff0c;连不上&#xff08;所有账号/客户端都连不上hive&#xff09;&#xff0c;但在chd里面看监控&#xff0c;服务器资源状态…

物联网之超声波测距模块、arduino、esp32

MENU 原理硬件电路设计软件程序设计 原理 超声波是一种频率高于20000Hz的声波&#xff0c;功率密度为p≥0.3W/cm&#xff0c;它的方向性好&#xff0c;反射能力强&#xff0c;易于获得较集中的声能。超声波用于许多不同的领域&#xff0c;比如检测物体和测量距离&#xff0c;清…

Unity 2d UI 实时跟随场景3d物体

2d UI 实时跟随场景3d物体位置&#xff0c;显示 3d 物体头顶信息&#xff0c;看起来像是场景中的3dUI&#xff0c;实质是2d UIusing System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; using UnityEngine.UI; /// <summary>…

【JS】无法阻止屏幕滚动

监听滚轮事件&#xff0c;阻止默认行为&#xff0c;但未生效&#xff0c;且控制台报错。 window.addEventListener(wheel, (e) > {e.preventDefault(); })这是因为现代浏览器使用 Passive 事件监听器&#xff0c;默认启用了 passive 模式以确保性能&#xff0c;不会调用 pr…

Cancer Cell|最新发表的单细胞成纤维细胞分析代码,速来学习!!!

简介 成纤维细胞在维持组织稳态、应对炎症和纤维化状况、帮助伤口愈合以及促进癌症进展的复杂舞蹈中起着关键作用。在癌症领域&#xff0c;成纤维细胞已成为肿瘤微环境&#xff08;TME&#xff09;中的核心人物&#xff0c;发挥着多方面的作用。这些作用包括细胞外基质&#xf…