JDK8新特性—常用函数式接口

2024-06-01 11:32
文章标签 jdk8 接口 函数 特性 常用

本文主要是介绍JDK8新特性—常用函数式接口,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

3.Consumer接口

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

抽象方法:accept
Consumer 接口中包含抽象方法 void accept(T t) ,意为消费一个指定泛型的数据。基本使用如:

package com.wjl.test;import java.util.function.Consumer;/*** Consumner接口* @author wjl**/
public class Demo6Consumer {private static void consumerString(Consumer<String> function) {function.accept("Hello");}public static void main(String[] args) {consumerString(s ->System.out.println(s));}
}

当然,更好的写法是使用方法引用

默认方法:andThen

如果一个方法的参数和返回值全都是 Consumer 类型,那么就可以实现效果:消费数据的时候,首先做一个操作,然后再做一个操作,实现组合。而这个方法就是 Consumer 接口中的default方法 andThen 。下面是JDK的源代码

    default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };}
备注: java.util.Objects 的 requireNonNull 静态方法将会在参数为null时主动抛出
NullPointerException 异常。这省去了重复编写if语句和抛出空指针异常的麻烦。

要想实现组合,需要两个或多个Lambda表达式即可,而 andThen 的语义正是“一步接一步”操作。例如两个步骤组合的情况:

package com.wjl.test;
import java.util.function.Consumer;
public class Demo7ConsumerAndThen {private static void consumerString(Consumer<String> one,Consumer<String> two) {one.andThen(two).accept("Hello");}public static void main(String[] args) {consumerString(s->System.out.println(s.toUpperCase()),s->System.out.println(s.toLowerCase()));}
}

运行结果将会首先打印完全大写的HELLO,然后打印完全小写的hello。当然,通过链式写法可以实现更多步骤的组合。

格式化打印信息
下面的字符串数组当中存有多条信息,请按照格式“ 姓名:XX。性别:XX。 ”的格式将信息打印出来。要求将打印姓名的动作作为第一个 Consumer 接口的Lambda实例,将打印性别的动作作为第二个 Consumer 接口的Lambda实例,将两个 Consumer 接口按照顺序“拼接”到一起。

package com.wjl.test;import java.util.function.Consumer;public class Demo8Printinfo {private static void printInfo(Consumer<String> one,Consumer<String> two,String[] array) {for(String info:array) {one.andThen(two).accept(info);}}public static void main(String[] args) {String[] array = { "迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男" };printInfo(s->System.out.print("姓名:"+s.split(",")[0]),s->System.out.println(" 性别:"+s.split(",")[1]), array);}
}

输出
姓名:迪丽热巴 性别:女
姓名:古力娜扎 性别:女
姓名:马尔扎哈 性别:男

4.Predicate接口

有时候我们需要对某种类型的数据进行判断,从而得到一个boolean值结果。这时可以使用java.util.function.Predicate 接口。

抽象方法:test
Predicate 接口中包含一个抽象方法: boolean test(T t) 。用于条件判断的场景:

package com.wjl.test;import java.util.function.Predicate;public class Demo9Predicate {private static void method(Predicate<String> predicate) {boolean isLong=predicate.test("Helloworld");System.out.println("字符串很长吗?"+isLong);}public static void main(String[] args) {method(s->s.length()>5);}
}

条件判断的标准是传入的Lambda表达式逻辑,只要字符串长度大于5则认为很长。

默认方法:and
既然是条件判断,就会存在与、或、非三种常见的逻辑关系。其中将两个 Predicate 条件使用“”逻辑连接起来实现“并且”的效果时,可以使用default方法 and 。其JDK源码为

    default Predicate<T> and(Predicate<? super T> other) {Objects.requireNonNull(other);return (t) -> test(t) && other.test(t);}

如果要判断一个字符串既要包含大写“H”,又要包含大写“W”,那么:

package com.wjl.test;import java.util.function.Predicate;public class Demo10PredicateAnd {private static void method(Predicate<String> one,Predicate<String> two) {boolean isValid=one.and(two).test("Helloworld");System.out.println("是否包含H和W:"+isValid);}public static void main(String[] args) {method(s->s.contains("H"),s->s.contains("W"));}
}

输出结果

是否包含H和W:false

默认方法:or
与 and 的“与”类似,默认方法 or 实现逻辑关系中的“或”。JDK源码为:

    default Predicate<T> or(Predicate<? super T> other) {Objects.requireNonNull(other);return (t) -> test(t) || other.test(t);}

如果希望实现逻辑“字符串包含大写H或者包含大写W”,那么代码只需要将“and”修改为“or”名称即可,其他都不变。

默认方法:negate
“与”、“或”已经了解了,剩下的“非”(取反)也会简单。默认方法 negate 的JDK源代码为:

    default Predicate<T> negate() {return (t) -> !test(t);}

从实现中很容易看出,它是执行了test方法之后,对结果boolean值进行“!”取反而已。一定要在 test 方法调用之前调用 negate 方法,正如 and 和 or 方法一样:

package com.wjl.test;import java.util.function.Predicate;public class Demo11PredicateNegate {private static void method(Predicate<String> predicate) {boolean isLong=predicate.negate().test("Helloworld");System.out.println("字符串很长吗:"+isLong);}public static void main(String[] args) {method(s->s.length()<5);}
}

输出

字符串很长吗:true

集合信息筛选

数组当中有多条“姓名+性别”的信息如下,请通过 Predicate 接口的拼装将符合要求的字符串筛选到集合
ArrayList 中,需要同时满足两个条件:

  1. 必须为女生;
  2. 姓名为4个字
package com.wjl.test;import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;public class Demo12Predicate {private static List<String> filter(String[] array,Predicate<String> one ,Predicate<String> two) {List<String> list=new ArrayList<>();for (String info : array) {if(one.and(two).test(info)) {list.add(info);}}return list;}public static void main(String[] args) {String[] array = { "迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男", "赵丽颖,女" };List<String> list = filter(array,s->"女".equals(s.split(",")[1]), s->s.split(",")[0].length()==4);System.out.println(list);}
}

5.Function接口

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

抽象方法:apply
Function 接口中最主要的抽象方法为: R apply(T t) ,根据类型T的参数获取类型R的结果。使用的场景例如:将 String 类型转换为 Integer 类型

package com.wjl.test;import java.util.function.Function;public class Demo13Function {private static void method(Function<String, Integer> function) {int num=function.apply("100");System.out.println(num+20);}public static void main(String[] args) {method(s->Integer.parseInt(s));//Lambda表达式method(Integer::parseInt);//方法引用的写法}
}

默认方法:andThen
Function 接口中有一个默认的 andThen 方法,用来进行组合操作。JDK源代码如

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {Objects.requireNonNull(after);return (T t) -> after.apply(apply(t));}

该方法同样用于“先做什么,再做什么”的场景,和 Consumer 中的 andThen 差不多:

package com.wjl.test;import java.util.function.Function;public class Demo14FunctionAndThen {private static void method(Function<String, Integer> one,Function<Integer, Integer> two) {int num=one.andThen(two).apply("10");System.out.println(num+20);}public static void main(String[] args) {method(str->Integer.parseInt(str)+10, i->i*=10);//220  第一个20 第二个20*10=200  andThen 220}
}

这篇关于JDK8新特性—常用函数式接口的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1020889

相关文章

java8的新特性之一(Java Lambda表达式)

1:Java8的新特性 Lambda 表达式: 允许以更简洁的方式表示匿名函数(或称为闭包)。可以将Lambda表达式作为参数传递给方法或赋值给函数式接口类型的变量。 Stream API: 提供了一种处理集合数据的流式处理方式,支持函数式编程风格。 允许以声明性方式处理数据集合(如List、Set等)。提供了一系列操作,如map、filter、reduce等,以支持复杂的查询和转

【操作系统】信号Signal超详解|捕捉函数

🔥博客主页: 我要成为C++领域大神🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 如何触发信号 信号是Linux下的经典技术,一般操作系统利用信号杀死违规进程,典型进程干预手段,信号除了杀死进程外也可以挂起进程 kill -l 查看系统支持的信号

java中查看函数运行时间和cpu运行时间

android开发调查性能问题中有一个现象,函数的运行时间远低于cpu执行时间,因为函数运行期间线程可能包含等待操作。native层可以查看实际的cpu执行时间和函数执行时间。在java中如何实现? 借助AI得到了答案 import java.lang.management.ManagementFactory;import java.lang.management.Threa

React+TS前台项目实战(十七)-- 全局常用组件Dropdown封装

文章目录 前言Dropdown组件1. 功能分析2. 代码+详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲全局Dropdown组件封装,可根据UI设计师要求自定义修改。 Dropdown组件 1. 功能分析 (1)通过position属性,可以控制下拉选项的位置 (2)通过传入width属性, 可以自定义下拉选项的宽度 (3)通过传入classN

SQL Server中,isnull()函数以及null的用法

SQL Serve中的isnull()函数:          isnull(value1,value2)         1、value1与value2的数据类型必须一致。         2、如果value1的值不为null,结果返回value1。         3、如果value1为null,结果返回vaule2的值。vaule2是你设定的值。        如

tf.split()函数解析

API原型(TensorFlow 1.8.0): tf.split(     value,     num_or_size_splits,     axis=0,     num=None,     name='split' ) 这个函数是用来切割张量的。输入切割的张量和参数,返回切割的结果。  value传入的就是需要切割的张量。  这个函数有两种切割的方式: 以三个维度的张量为例,比如说一

vue3项目将所有访问后端springboot的接口统一管理带跨域

vue3项目将所有访问后端springboot的接口统一管理带跨域 一、前言1.安装Axios2.创建Axios实例3.创建API服务文件4.在组件中使用API服务 二、跨域三、总结 一、前言 在Vue 3项目中,统一管理所有访问后端Spring Boot接口的最佳实践是创建一个专门的API服务层。这可以让你的代码更加模块化、可维护和集中管理。你可以使用Axios库作为HTT

帆软报表常用操作

欢迎来到我的博客,代码的世界里,每一行都是一个故事 🎏:你只管努力,剩下的交给时间 🏠 :小破站 帆软报表常用操作 多序号实现使用数据集作为参数空白页或者竖线页修改页面Title金额,或者保留两位小数等等设置日期格式显示图片使用公式 多序号实现 所用函数为SEQ(),如果一张报表中需要用到多个序号,那么就需要加入参数SEQ(1),SEQ(

常用MQ消息中间件Kafka、ZeroMQ和RabbitMQ对比及RabbitMQ详解

1、概述   在现代的分布式系统和实时数据处理领域,消息中间件扮演着关键的角色,用于解决应用程序之间的通信和数据传递的挑战。在众多的消息中间件解决方案中,Kafka、ZeroMQ和RabbitMQ 是备受关注和广泛应用的代表性系统。它们各自具有独特的特点和优势,适用于不同的应用场景和需求。   Kafka 是一个高性能、可扩展的分布式消息队列系统,被设计用于处理大规模的数据流和实时数据传输。它

神经网络第三篇:输出层及softmax函数

在上一篇专题中,我们以三层神经网络的实现为例,介绍了如何利用Python和Numpy编程实现神经网络的计算。其中,中间(隐藏)层和输出层的激活函数分别选择了 sigmoid函数和恒等函数。此刻,我们心中不难发问:为什么要花一个专题来介绍输出层及其激活函数?它和中间层又有什么区别?softmax函数何来何去?下面我们带着这些疑问进入本专题的知识点: 1 输出层概述 2 回归问题及恒等函数 3