accept函数_使用函数式接口

article/2025/11/1 11:54:06
61dab099181dc3f9c2de267ca8469b10.png

像上几章提到的,函数式接口定义且只定义了一个抽象方法。函数式接口很有用,因为抽象方法的签名可以描述Lambda表达式的签名。函数式接口的抽象方法的签名成为函数描述符。所以为了应用不同的Lambda表达式,你需要一套能够描述常见函数描述符的函数式接口。Java API中已经有了几个函数式接口,比如之前几章提到的Comparator,Runnable和Callable。

Java8的库设计师帮你在java.util.function包中引入了几个新的函数式接口。我们接下来会介绍Predicate,Consumer和Function。

Predicate

java.util.function.Predicate接口定义了一个名叫test的抽象方法,它介绍范型T对象,并返回一个boolean。这恰恰和你先前创建的一样,现在就可以直接使用了。在你需要表示一个涉及类型T的布尔表达式时,就可以使用这个接口。比如,你可以定义一个接受String对象的Lambda表达式:

@FunctionalInterfacepublic interface Predicate{boolean test(T t);}public static  List filter(List list , Predicate

如果你去查Predicate接口的Javadoc说明,可能会注意到诸如and和or等其他方法。现在你不用太计较这些,我们会在后面讨论。

Consumer

java.util.function.Consumer 定义了一个名叫accept的抽象方法,它接受泛型T的对象,没有返回void。你如果需要访问类型T的对象,并对其执行某些操作,就可以使用这个接口。比如,你可以用它来创建一个forEach方法,接受一个Intergers的列表,并对其中每个元素执行操作。在下面的代码中,你就可以使用这个forEach方法,并配合Lambda来打印列表中的所有元素。

@FunctionalalInterfacepublic interface Consumer{void accept(T t);}public static  void forEach(List list , Consumer c){for(T i:list){  c.accept(i);  }}forEach(Arrays.asList(1,2,3,4) , (Integer i) -> System.out.println(i));

Function

java.util.function.Function接口定义了一个叫做apply的方法,它接受一个泛型T的对象,并返回一个泛型R的对象。如果牛需要定义一个Lambda,将输入对象的信息映射到输出,就可以使用这个接口(比如提取苹果的重量,或把字符串映射为它的长度)。在下面的代码中,会向你展示如何利用它来创建一个map方法,以将一个String列表映射到包含每个String长度的Integer列表。

@FunctionalInterfacepublic interface Function{R apply(T t)}public static  List map(List list , Function f){  List result = new ArrayList<>();  for(T s:list){  result.add(f.apply(s));  }  return result;}List l = map(Arrays.asList("guan,zhu,wo"),(S);

原始类型特化

我们介绍了三个泛型函数式接口:Predicate,Consumer和Function。还有些函数式接口专为某些类型而设计。

回顾一下:Java类型要么是引用类型(比如Byte,Integer,Object,List),要么是原始类型(int,double,byte,char)。但是泛型(比如Consumer 中的T)只能绑定应用类型。这是由泛型内部的实现方式造成的。因此,在Java里有一个原始类型转换为对应的引用类型的机制。这个机制叫做装箱(boxing)。相反的操作,也就是将引用类型转换为对应的原始类型,叫做拆箱(unboxing)。Java还有一个自动装箱机制来帮助程序员执行这一个任务:装箱和拆箱操作是自动完成的。比如,这就是为什么下面的代码是有效的(一个int被装箱成为Integer):

List list = new ArrayList<>();for(int i = 300 ; i < 400;i++){list.add(i);}

但这在性能方面是要付出代价的。装箱后的值本质就是把原始类型包裹起来,并保存在堆里面。因此,装箱后的值需要更多的内存,并需要额外的内存搜索来获取被包裹饿的原始值。

Java 8为我们前面说的函数式接口带来一个专门的版本,以便在输入和输出都是原始类型时避免自动装箱的操作。比如,在下面的代码中,使用IntPredicate就避免了对值1000进行装箱操作,但要是用Predicate就会把参数1000装箱到一个Integer对象中:

public interface IntPredicate{boolean test(int t);}IntPredicate evenNumbers = (int i) -> i % 2 == 0;evenNumbers.test(1000);Predicate oddNumbers = (Integer i) -> i % 2 == 1;oddNumbers.test(1000);

一般来说,针对专门的输入参数类型的函数式接口的名称都要加上对应的原始类型前缀,比如D欧巴了 Predicate,IntConsumer,LongBinaryOperator等。Function接口还有针对输出参数的变种:ToIntFunction,IntToDoubleFunction等。

04964d21dc172cc59b8346f626680ecc.png

为了总结关于函数式接口和Lambda的讨论,下面总结了一些使用案例、Lambda的例子,以及可以使用的函数式接口。

01f7ce374db318199c44847f9c75f748.png

请注意,任何函数式接口都不允许抛出受检异常。如果你需要Lambda表达式来抛出异常,有两种方法:定义一个自己的函数式接口,并且声明受检异常,或者把Lambda包在一个try/catch块中。

现在你知道如何创建Lambda,在哪里以及如何使用他们了。后面的章节我们会介绍一些更高级的细节:编译器如何对Lambda做类型检查,以及你应当了解的规则,诸如Lambda在自身内部引用局部变量,还有和void兼容的Lambda等。


http://chatgpt.dhexx.cn/article/hCmMmGY0.shtml

相关文章

accept函数(TCP)

accept函数&#xff08;TCP&#xff09; #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);功能&#xff1a;阻塞等待客户端的连接请求 sockfd&#xff1a;文件描述符&#…

Context context = getApplicationContext()

使用getApplicationContext 取得的是当前app所使用的application&#xff0c;这在AndroidManifest中唯一指定。意味着&#xff0c;在当前app的任意位置使用这个函数得到的是同一个Context 1、Context概念 其实一直想写一篇关于Context的文章&#xff0c;但是又怕技术不如而误人…

AutoCompleteTextView

自动完成的提供建议的文本 使用方法 //arrays.xml <?xml version"1.0" encoding"utf-8"?> <resources><array name"city_name"><item>Chengdu</item><item>Beijing</item><item>Tianjin<…

http状态码、accept、Content-Type

一、http状态码 &#xff08;1&#xff09;http状态码 1XX&#xff1a;信息&#xff0c;服务器收到请求&#xff0c;需要请求者继续执行操作 2XX&#xff1a;成功&#xff0c;操作被成功接收并处理 3XX&#xff1a;重定向&#xff0c;需要进一步的操作以完成请求 4XX&#xf…

Gated-Attention Readers for Text Comprehension

Gated-Attention Readers for Text Comprehension 文本理解中的门控attention阅读器 code Abstract 本文研究的是完形填空问题式MRC&#xff0c;作者提出的门控注意力阅读器集中了多跳结构和一种新的注意力计算机制&#xff08;基于query嵌入和RNN文档阅读器中间状态之间的…

Html中Input的accept属性

Accept属性规定通过在文件上传提交的服务接受的文件类型 但是accept属性只能适用在Html input类型为文件类型&#xff0c;也就是说其他类型的input accept属性就不适用 我写的这个过滤文件属性是针对于后缀名为.xls的文件&#xff0c;所有的文件只要不是.xls后缀就不显示出来…

ApplicationContext

如果说BeanFactory是Spring的心脏&#xff0c;那么Application就是完整的身躯。ApplicationContext就是由BeanFactory派生出来的。 1、ApplicationContext ApplicationContext的主要实现类是ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,前者默认从类路径…

ActionContext

1、ActionContext翻译成中文就是Action的上下文&#xff08;为什么说是上下文&#xff0c;是应为他的生命周期长&#xff0c;和我们的项目的生命周期是相同的&#xff0c;我们很多公共的东西都放在里面&#xff0c;方便存取 &#xff09;&#xff0c;ActionContext是struts2的上…

readonly option is set (add ! to override)错误的解决

在mac电脑或linux系统中经常操作修改某个文件后保存退出出现readonly option is set (add ! to override)。如图&#xff1a; 正常情况下按 A进入编辑模式修改文件后按ESC退出编辑模式&#xff0c;:wq命令保存退出&#xff0c;但经常会遇到以上显示&#xff0c;文件权限只读或者…

ByteBuffer的allocate和allocateDirect

在Java中当我们要对数据进行更底层的操作时&#xff0c;通常是操作数据的字节&#xff08;byte&#xff09;形式&#xff0c;这时常常会用到ByteBuffer这样一个类。ByteBuffer提供了两种静态实例方式&#xff1a; Java代码 public static ByteBuffer allocate(int capacity…

直接内存 直接内存的释放和回收

直接内存 特点 不属于Java虚拟机管理&#xff0c;属于系统内存&#xff1b;属于操作系统&#xff0c;常见于NIO操作时&#xff0c;比如ByteBuffer【】用于数据缓冲区分配回收成本较高&#xff0c;但读写性能高&#xff1b;不受JVM内存回收管理 文件读写过程 java不具备磁盘…

解决The‘Access-Control-Allow-Origin‘ header contains multiple values‘*, ....‘, but only one is allowed

报错内容&#xff1a; Access to XMLHttpRequest at ‘http://www.z…n.com/api/login’ from origin ‘http://z…n.com’ has been blocked by CORS policy: The ‘Access-Control-Allow-Origin’ header contains multiple values ‘*, http://z…n.com’, but only one is …

C++中std::allocator的使用

标准库中包含一个名为allocator的类&#xff0c;允许我们将分配和初始化分离。使用allocator通常会提供更好的性能和更灵活的内存管理能力。 new有一些灵活性上的局限&#xff0c;其中一方面表现在它将内存分配和对象构造组合在了一起。类似的&#xff0c;delete将对象析构和内…

alloc的流程

1⃣️ 2⃣️ 3⃣️ 现在我们看的objc源码都是2.0的版本&#xff0c;之前还有一个1.0的版本 4⃣️ 5⃣️核心方法 最主要的就是最下面三个方法 他的最重要作用就是开辟内存 cls->instanceSize 先计算出需要的内存空间大小这个大小只和对象的成员变量有关 在没有成员变量…

ByteBuffer.allocate()与allocateDirect()的区别

allocate()产生的是HeapByteBuffer的实例, 本质上是一个no direct buffer, allocateDirect()产生的是DirectByteBuffer的实例, 本质是一个direct buffer 主要区别 buffer的创建方式不同, no direct buffer还可以通过封装已存在的byte array来产生执行IO操作时不同, no direct …

ByteBuffer常用方法与分析

目录 目标 常用API 工具方法 演示案例 allocate(int capacity)和allocateDirect(int capacity) put()和get() flip()和hasRemaining() clear() compact() wrap() 总结 目标 掌握ByteBuffer常用方法&#xff0c;分析ByteBuffer对象在切换读写模式的情况下基本属性的变…

allocate与allocateDirect的性能测试

allocate与allocateDirect的性能测试 测试工具JMH测试代码JMH结果结论 测试工具JMH java基准测试框架 测试代码 直接分配系统内存(allocateDirect) -测试申请内存性能JVM堆分配内存(allocate)-测试申请内存性能直接内存-操作-连续二十次添加(allocateDirect)-测试内存操作性能…

ByteBuffer.allocate()与ByteBuffer.allocateDirect()方法的区别

在Java中当我们要对数据进行更底层的操作时&#xff0c;一般是操作数据的字节&#xff08;byte&#xff09;形式&#xff0c;这时经常会用到ByteBuffer这样一个类。ByteBuffer提供了两种静态实例方式&#xff1a; public static ByteBuffer allocate(int capacity) public s…

8、ByteBuffer(方法演示2(allocate堆内存和allocateDirect直接内存))

ByteBuffer&#xff08;方法演示2&#xff08;allocate堆内存和allocateDirect直接内存&#xff09;&#xff09; Allocate&#xff1a;java堆内存:读写效率低&#xff0c;收到gc的影响&#xff08;因为我们的java对象也是存在堆内存的&#xff09; &#xff01;&#xff01;…

03 Java NIO allocateDirect()和allocate()区别

03 Java NIO allocateDirect和allocate区别 allocateDirect()和allocate()区别直接与非直接缓冲区直接与非直接缓冲区 源码分析 allocateDirect()和allocate()区别 allocateDirect&#xff1a;分配直接缓冲区&#xff0c;将缓冲区简历在物理内存中&#xff0c;可以提交效率 all…