常用函数式接口的学习

文章目录

  • 定义
  • 常用的函数式接口
    • Supplier
      • 演示代码
    • Consumer
      • accept 方法
        • 演示代码
      • andThen 方法
        • 演示代码
    • Predicate
      • test 方法
      • and 方法
        • 演示代码
      • or 方法
      • negate 方法
    • Function
      • apply 方法
        • 演示代码
      • andThen 方法
        • 演示代码

定义

有且仅有一个抽象方法的接口称之为“函数式接口”,但是“函数式接口”依旧可以包含其它的非抽象方法,例如,默认方法、静态方法、私有方法等。关于什么是默认方法、静态方法、私有方法请参见《Java声明定义抽象类_接口_继承_实现》

函数式接口的实现类对象,可以通过 Lambda 表达式来构造。

常用的函数式接口

java.util.function 包下有很多 JDK 提供的函数式接口。

Supplier

java.util.function.Supplier<T>,接口包含一个无参的方法:public abstract T get()。用来获取一个泛型参数指定类型的对象数据。由于这是一个函数式接口,也就意味着对应的 Lambda 表达式需要“对外提供”一个符合泛型类型的对象数据。

public interface Supplier<T>,称之为生产型接口,指定接口的泛型是什么类型,那么接口中的方法就会返回(好像生活中的生产)什么类型的数据。

演示代码

package priv.lwx.javaprac.functionalinterface;import java.util.function.Supplier;/*** @ClassName Demo04Supplier* @Description 函数式接口Supplier的演示代码* @Author liaowenxiong* @Version 1.0* @date 2021/9/7 下午4:40*/
public class Demo04Supplier {public static void main(String[] args) {System.out.println(getString(() -> "杨思敏"));}public static String getString(Supplier<String> sup) { // 接口指定了泛型的具体数据类型,相关抽象方法涉及到的泛型的具体数据类型就确定了,实现类就需要根据已确定的数据类型来实现抽象方法return sup.get();}
}

Consumer

java.util.function.Consumer<T>,该接口正好与 Supplier<T> 接口相反,它不是生产一个数据,而是消费一个数据,其数据类型由泛型来决定。

accept 方法

Consumer<T> 接口中含有一个抽象方法 public abstract void accept(T t),用来消费一个指定泛型类型的数据,所谓消费数据就是使用数据,例如,打印输出、计算等

演示代码

package priv.lwx.javaprac.functionalinterface;import java.util.function.Consumer;/*** @ClassName Demo16Consumer* @Description TODO* @Author liaowenxiong* @Version 1.0* @date 2021/9/10 下午2:56*/
public class Demo16Consumer {public static void main(String[] args) {// 定义一个字符串数组,存放姓名String[] names = {"潘金莲", "李瓶儿", "武媚娘"};// 调用方法printArray,将数组内容打印输出printArray(names, (t) -> {for (String s : t) {System.out.println(s);}});}// 定义一个方法用来打印输出字符串数组的内容,传入两个参数:字符串数组、Consumer对象(即Lambda表达式)public static void printArray(String[] strs, Consumer<String[]> action) {action.accept(strs);}
}

andThen 方法

源代码如下所示:

default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { this.accept(t); after.accept(t); };
}

return (T t) -> { this.accept(t); after.accept(t); } 这行代码做了下面几件事

1.在某个方法体内去定义另外一个方法(实现 Consumer 的抽象方法 accept),目前也就是只有 Lambda 表达式可以这样做了
2.创建了一个对象,即接口 Consumer 的实现类对象
3.this 是指执行方法 andThen 时的当前对象,并不是执行方法 accept 时的当前对象
4.执行方法 andThen 时,就已经确定了 this 的身份,所以这里要特别注意,不要被绕进去了

注意:Lambda 表达式的实现类并没有生成单独的类文件,所以实现方法的代码应该还在外部类(宿主类)中

演示代码

package priv.lwx.javaprac.functionalinterface;import java.util.function.Consumer;public class Demo05Consumer {public static void main(String[] args) {String str = "刘德华";// 泛型接口声明的变量接收实现类的对象,必须指明具体的数据类型,换句话说,使用Lambda表达式创建对象必须指定具体的数据类型Consumer<String> con1 = t -> System.out.println(t); // 这是对accept方法的一种实现,打印输出字符串Consumer<String> con2 = t -> System.out.println(t.length()); // 这是对accept方法的另外一种实现,输出字符串的长度// andThen方法返回的是另外一个实现类的对象,和对象con1和con2分属三个不同的实现类// 这个实现类对accept方法进行了另外一种实现,就是调con1的accept方法,调con2的accept方法,具体看方法andThen的源代码// 下面这行代码其实执行了三个Consumer对象的accept方法,且它们分属不同的实现类,因此方法accept也是不同的实现,只是名称相同而已con1.andThen(con2).accept(str); // 输出的结果是:刘德华 3}
}

Predicate

test 方法

含有一个抽象方法:
public abstract boolean test(T t),用来对指定的数据进行判断,符合条件返回 true,不符合返回 false

and 方法

表示“并且”关系,实现逻辑关系中的“与”,将多个 Predicate 对象所代表的条件进行“与”运算。
“与”运算符为“&&”。

演示代码

package priv.lwx.javaprac.functionalinterface;import java.util.function.Predicate;/*** @ClassName Demo08Predicate* @Description Predicate的and方法演示代码* @Author liaowenxiong* @Version 1.0* @date 2021/9/8 下午9:17*/
public class Demo08Predicate {public static void main(String[] args) {String str = "sdfdsafds";/*判断字符串的长度是否大于5,并且包含小写字母a,如果两个条件都满足返回true,否则返回false*/boolean b = checkString(str, (t) -> {return t.length() > 5;}, (t) -> {return t.contains("a");});System.out.println(b);}/*** @return boolean* @MethodName checkString* @Author liaowenxiong* @Description 声明定义一个方法,用于传递一个字符串和两个条件,* 判断指定的字符串,如果两个条件都满足则返回true,否则返回false* @Date 下午9:24 2021/9/8* @Param [str, p1, p2]*/public static boolean checkString(String str, Predicate<String> p1, Predicate<String> p2) {boolean b = p1.and(p2).test(str);return b;}
}

or 方法

表示“或者”关系,实现逻辑关系中的“或”,将多个 Predicate 对象所代表的条件进行“或”运算。
“或”运算符为“||”。

negate 方法

实现逻辑关系中的“非”,将多个 Predicate 对象所代表的条件进行“非”运算。
“非”也可以称之为“取反”,非真就是假,非假就是真。
“非”运算符为“!”。

Function

java.util.function.Function<T,R>,接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。

apply 方法

public abstract R apply(T t),根据类型 T 的参数获取类型 R 的结果。
使用的场景,例如,将 String 类型转换为 Integer 类型。

演示代码

package priv.lwx.javaprac.functionalinterface;import java.util.function.Function;/*** @ClassName Demo14Function* @Description java.util.function.Function<T, R>,接口用来根据一个类型的数据得到* 另一个类型的数据,前者称为前置条件,后者称为后置条件。* @Author liaowenxiong* @Version 1.0* @date 2021/9/9 下午1:35*/
public class Demo14Function {public static void main(String[] args) {String str = "250";// 调用方法toInteger,传递字符串和一个Lambda表达式int i = toInteger(str, (t) -> {return Integer.valueOf(t);});System.out.println(i);}/*** 定义一个方法,方法的参数传递一个字符串类型的整数,再传递一个Function对象,* 泛型使用<String,Integer>,使用Function对象的方法apply,把字符串类型的* 整数转换为Integer类型的整数,并返回该整数*/public static Integer toInteger(String str, Function<String, Integer> func) {Integer i = func.apply(str);return i;}}

andThen 方法

先将一种类型的数据转换成另外一种类型的数据,再将另外一种类型的数据转换成其它类型,以此类推

演示代码

package priv.lwx.javaprac.functionalinterface;import java.util.function.Function;/*** @ClassName Demo15Function* @Description 需求:* 把String类型的"123"转换成Integer类型,把转换后端结果加10,* 把增加后的Integer数据,再转换成String* @Author liaowenxiong* @Version 1.0* @date 2021/9/9 下午3:10*/
public class Demo15Function {public static void main(String[] args) {String str = "123";// 调用方法computerStringInteger,传入要计算的字符串整数和"加数"String r = addStringInteger(str, 10);System.out.println(r);}/*** 定义一个方法,对指定字符串型的整数进行加法计算并返回增加后的字符串* 此方法接收两个参数:* 1.字符串类型的整数* 2.整数型的加数*/public static String addStringInteger(String str, int i) {Function<String, Integer> func = (t) -> {// 将字符串数据转换成Integer类型的数据,再加上参数 ireturn Integer.parseInt(t) + i;};Function<Integer, String> func2 = (t) -> {// 将Integer类型的数据,转换成字符串类型return Integer.toString(t);};// 将字符串转换成Integer,再转换成字符串返回return func.andThen(func2).apply(str);}
}

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

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

相关文章

如何创建虚拟硬盘 + os 读取硬盘参数代码

【0】README 0.1&#xff09; 本文旨在演示如何利用 bximage 创建虚拟硬盘&#xff1b;0.2&#xff09; 利用 os 读取硬盘参数&#xff0c; source code from orange’s implemention of a os , for complete code , please visit https://github.com/pacosonTang/Orange-s-OS…

内联脚本被视为是有害的_数据类被认为有害

内联脚本被视为是有害的这篇博客文章解释了从我参与的项目之一中删除Lombok项目的动机。 它反映了我的个人观点&#xff0c;并不妨碍特定的技术。 大约三年前&#xff0c;我认识了Project Lombok &#xff0c;这是一个添加Java代码的库。 我从一开始就喜欢它&#xff0c;因为它…

win10可用空间变成未分配_教你两种方法有效利用Win10未分配的空间 - 易我科技...

Haley 于2020/08/24更新 磁盘分区管理摘要文中介绍了两种方法充分利用Windows10未分配空间&#xff0c;分别为1)格式化Win10未分配空间来创建新的分区&#xff0c;2)在分区上添加未分配空间。我的Win 10计算机上有一个大小99GB的未分配空间 :「我在Windows计算机上安装了两个硬…

selenium编写脚本_Selenium脚本编写技巧和窍门

selenium编写脚本如果您刚刚开始学习Selenium&#xff0c;则以下技巧和窍门将成为您的救星。 这些技巧和窍门具有您可能会忘记的所有基本知识&#xff0c;将帮助您记住所有这些。 您只需浏览一次&#xff0c;几秒钟后您便会了解所有内容。 让我们一一看一下所有的技巧和窍门。 …

div和div之间画横线_HTML如何在两个div标签中间画一条竖线

近日在画一个界面的时候&#xff0c;遇到一个需求&#xff1a;在界面当中画一条竖线&#xff0c;且这条竖线在高度上需要自动占满整个父div(即这条竖线的高度和两个div中较高的一个等高)。往常我们画一条横线直接用标签即可&#xff0c;当画一条竖线的时候发现找不到标签。在网…

静态类型/静态分派/动态分派/单分派/多分派

文章目录静态类型/实际类型方法解析静态分派动态单分派参考静态类型/实际类型 Human woman new Woman(); // Human就是静态类型&#xff0c;其实就是变量编译时类型&#xff0c;Woman就是实际类型 Man man new Man(); // 静态类型和实际类型都是Man方法解析 Class 文件的编…

jvm回收垃圾_没有垃圾回收的JVM

jvm回收垃圾JVM社区不断增加新的GC&#xff0c;最近又添加了一个新的GC&#xff0c;它被称为Epsilon &#xff0c;是非常特殊的一个。 Epsilon仅分配内存&#xff0c;但不会回收任何内存。 看起来好像不执行任何垃圾回收的GC用途是什么。 这种类型的垃圾收集器有特殊用途&…

C打印函数printf的一种实现原理简要分析

【0】README 0.1&#xff09;本文旨在对 printf 的 某一种 实现 原理进行分析&#xff0c;做了解之用&#xff1b;0.2&#xff09; vsprintf 和 printf.c 的源码&#xff0c;参见 https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/p309 【1】pr…

wireshark提取流量包中的文件_[技术]Wireshark抓取的数据包提取文件

0x00 简介本期主要会教大家如何从流量中还原出来文件。下面我将会用多种办法来讲解。使用系统&#xff1a;Kali Linux0x01 tcpxtract工具网络流量提取文件(方法1)Kali Linux默认没有安装该工具&#xff0c;需要自己安装安装命令&#xff1a;sudo apt install tcpxtract使用方法…

java设计模式适配器模式_Java中的适配器设计模式

java设计模式适配器模式适配器设计模式是一种结构设计模式 &#xff0c;可以帮助我们连接到通过不同接口公开相似功能的旧版或第三方代码。 适配器的现实世界是我们用来将USB电缆连接到以太网端口的类比。 在设计一个面向对象的应用程序时&#xff0c;当我们的客户期望一个特…

技术路线的选择重要但不具有决定性

微软在技术上连续大动作&#xff0c;如果放在几年前&#xff0c;我相信微软粉丝们一定是欢声雷动&#xff0c;不过这次情况有点不太一样&#xff0c;在网上看到有人在抱怨微软技术更新速度太快而且四面出击&#xff0c;还有人扬言要改弦更张&#xff0c;投奔Linux或者Java阵营。…

nproc是什么意思_top/htop内容的含义

uptimeuptime命令显示了load avg&#xff0c;它其实是读取的/proc/uptime文件&#xff1a;/proc/uptime 文件cat /proc/uptime9592411.58 9566042.33第一个是系统启动了多久(单位s)&#xff0c;第二个意思是系统启动以来&#xff0c;cpu idle花费的时间(单位s)。多核机器上&…

进程间通信(IPC)+进程加锁解锁

【0】README 0.1&#xff09; source code and text description are from orange’s implemention of a os&#xff1b;0.2&#xff09; for complete code , please visit https://github.com/pacosonTang/Orange-s-OS/tree/master/ipc_8 【1】看看&#xff0c;我们的进程代…

QA与测试到底有什么区别?

文章目录引言QA与测试的区别&#xff1f;QA、QC、QM的关系与区别&#xff1f;QA工作内容与职责引言 近期微信公众号后台有同学留言问&#xff1a; QA与测试的区别&#xff1f; QA、QC、QM的区别&#xff1f;以及QA的工作内容与职责。 针对这些问题我查阅了一些资料然后结合自…

java 进程运行时间_将Java类作为子进程运行

java 进程运行时间我本周需要将Java类&#xff08;而不是jar&#xff09;作为子进程运行。 更确切地说&#xff0c;我想从测试内部产生一个新进程&#xff0c;而不是直接在测试内部&#xff08;进程内&#xff09;运行它。 我不认为这是幻想或复杂的事情。 但是&#xff0c;这不…

划分vlan实验心得体会_思科:相同vlan,不同交换机之间的通信

实验拓扑如下&#xff1a;VPC 26 IP 23.1.1.3 24 VLAN20VPC 25 IP 12.1.1.2 24 VLAN10VPC1 IP 12.1.1.1 24 VLAN10VPC2 IP 23.1.1.2 24 VLAN20IOL交换机命名为SW1 先配置SW1的vlan10 和20检查SW1的vlan信息配置SW1的vlan10 和20检查SW2的vlan信息下一步将SW1和SW2连接的接口改为…

如何通过W3school学习JS/如何使用W3school的JS参考手册

文章目录学习JS对象DOM 对象HTML 对象JS 的常规类型教程学习 jQuery学习平台&#xff1a; W3school类似的学习平台&#xff1a; 菜鸟教程学习JS对象 DOM 对象 HTML 对象 JS 的常规类型 教程 学习 jQuery

快速选择

【0】README 0.1&#xff09;设有一组N 个数而要确定其中第k 个最小&#xff08;大&#xff09;者&#xff0c;我们称之为选择问题&#xff1b; 选择问题的解法&#xff1f;” 解法即为 快速选择算法&#xff1b; 0.2&#xff09; 快速选择是对 快速排序 改造而来&#xff0…

java模板方法模式_Java中的模板方法模式

java模板方法模式模板方法模式是一种行为模式&#xff0c;建议在超类中更一般地定义算法。 该算法是在称为模板方法的方法中定义的。 子类仅定义更具体的算法步骤的实现。 使用这种设计模式的好处是&#xff0c;算法后面的任何更改只会影响超类中的代码。 此外&#xff0c;它还…

hive 索爱_达内大数据云计算

第一阶段(Java基础)Java语言的高级特性静态导入、自动封箱拆箱、可变参数、增强for、枚举、类加载器、反射、内省、泛型、注解、动态代理回掌握Java语言的高级特性Java多线程多线程加强、线程池、Thread Local掌握Java线程池技术&#xff0c;掌握线程的Join、notify、notifyAll…