JAVA中的函数接口,你都用过吗
公众号「架构成长指南」,专注于生产实践、云原生、分布式系统、大数据技术分享。
在这篇文章中,我们将通过示例来学习 Java 函数式接口。
函数式接口的特点
- 只包含一个抽象方法的接口称为函数式接口。
- 它可以有任意数量的默认静态方法,但只能包含一个抽象方法。它还可以声明对象类的方法。
- 函数接口也称为单一抽象方法接口或SAM 接口。
- 函数式接口只有在没有任何抽象方法时才可以扩展另一个接口。
- Java API 具有许多单方法接口,例如 Runnable、Callable、Comparator、ActionListener等。它们可以使用匿名类语法来实现和实例化。
接口示例
创建一个自定义的Sayable
接口,这是一个使用@FunctionalInterface
注解的函数式接口。
@FunctionalInterface
注解表示该接口是一个函数式接口,并且只包含一个抽象方法。
自定义函数接口示例
@FunctionalInterface
interface Sayable{
void say(String msg); // abstract method
}
让我们通过main()
方法来演示一个自定义的函数式接口。我们使用Lambda表达式来实现函数式接口。
public class FunctionalInterfacesExample {
public static void main(String[] args) {
Sayable sayable = (msg) -> {
System.out.println(msg);
};
sayable.say("Say something ..");
}
}
Predefined 函数接口
Java提供了Predefined
的函数式接口,通过使用 lambda 和方法引用来处理函数式编程。
Predicate
是检查条件的函数,它接受一个参数并返回boolean结果。
让我们来看一下Predicate接口的内部实现。
import java.util.function.Predicate;
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
// 默认方法的实现
return (t) -> test(t) && other.test(t);
}
// 其他默认方法和静态方法...
}
Predicate接口只包含一个抽象方法test(T t)同时它还包含默认方法和静态方法。
让我们创建一个示例来演示Predicate函数式接口的用法:
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 使用Predicate接口检查数字是否为偶数
Predicate<Integer> evenNumberPredicate = number -> number % 2 == 0;
System.out.println("Even numbers:");
printNumbers(numbers, evenNumberPredicate);
// 使用Predicate接口检查数字是否大于5
Predicate<Integer> greaterThanFivePredicate = number -> number > 5;
System.out.println("Numbers greater than 5:");
printNumbers(numbers, greaterThanFivePredicate);
}
public static void printNumbers(List<Integer> numbers, Predicate<Integer> predicate) {
for (Integer number : numbers) {
if (predicate.test(number)) {
System.out.println(number);
}
}
}
}
Function 函数接口
Function函数接口是Java中的一个函数式接口,它定义了一个接收一个参数并返回结果的函数。它的定义如下:
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
Function接口有两个泛型参数:T表示输入参数的类型,R表示返回结果的类型。它包含一个抽象方法apply(),接收一个类型为T的参数,并返回一个类型为R的结果。
Function接口常用于将一个值转换为另一个值,或者对输入值进行处理和计算。它可以被用于各种场景,如数据转换、映射、计算和处理等。
以下是一个使用Function函数接口的示例:
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
// 创建一个Function接口来将字符串转换为大写
Function<String, String> uppercaseFunction = str -> str.toUpperCase();
// 使用Function接口将字符串转换为大写
String result = uppercaseFunction.apply("hello world");
System.out.println(result); // 输出: HELLO WORLD
// 使用Function接口将字符串转换为其长度
Function<String, Integer> lengthFunction = str -> str.length();
int length = lengthFunction.apply("hello");
System.out.println(length); // 输出: 5
}
}
Supplier 函数接口
Supplier用于表示一个提供(供应)结果的函数。它通常用于延迟计算或在需要时生成值。通过调用get()方法,我们可以获取由Supplier实例提供的结果。
以下是Consumer接口的实现
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
由于Supplier接口只有一个抽象方法,因此可以使用lambda表达式快速创建Supplier实例。下面是一个示例:
import java.util.Random;
import java.util.function.Supplier;
public class Main {
public static void main(String[] args) {
// 创建一个Supplier接口来生成随机整数
Supplier<Integer> randomIntegerSupplier = () -> new Random().nextInt();
// 使用Supplier接口生成随机整数
int randomNumber = randomIntegerSupplier.get();
System.out.println(randomNumber);
// 创建一个Supplier接口来生成当前时间戳
Supplier<Long> timestampSupplier = () -> System.currentTimeMillis();
// 使用Supplier接口生成当前时间戳
long timestamp = timestampSupplier.get();
System.out.println(timestamp);
}
}
Consumer 函数接口
Consumer用于表示接受一个参数并执行某些操作的函数。它定义了一个名为accept(T t)
的抽象方法,接受一个参数,并且没有返回值。
以下是Consumer接口的简化版本
@FunctionalInterface
public interface Consumer<T> {
void accept(T arg0);
}
Consumer接口适用于那些需要对传入的参数进行某种操作,而不需要返回结果的情况。它可以用于在不同的上下文中执行各种操作,如打印、修改状态、更新对象等。
下面是一个使用Consumer接口的示例:
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
public class Main {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Dave");
// 使用Consumer接口打印每个名字
Consumer<String> printName = name -> System.out.println(name);
names.forEach(printName);
// 使用Consumer接口修改每个名字为大写形式
Consumer<String> uppercaseName = name -> {
String uppercase = name.toUpperCase();
System.out.println(uppercase);
};
names.forEach(uppercaseName);
}
}
在上述示例中,我们创建了两个Consumer接口的实例。第一个printName用于打印每个名字,第二个uppercaseName用于将每个名字转换为大写形式并打印。
通过调用forEach()方法并传入相应的Consumer接口实例,我们可以对列表中的每个元素执行相应的操作。在示例中,我们对名字列表中的每个名字进行了打印和转换操作。
Consumer接口的使用场景包括遍历集合、处理回调函数、更新对象状态等。它提供了一种简洁的方式来执行针对输入参数的操作,使得代码更加清晰和模块化。
BiFunction 函数接口
BiFunction
函数式接口表示接受两个参数并返回结果的函数。它定义了一个名为apply(T t, U u)
的抽象方法,接受两个参数,并返回一个结果。
让我们来看一下BiFunction
接口的简化版本。
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T arg0, U arg1);
}
BiFunction
接口适用于那些需要接受两个输入参数并产生结果的情况。它可以用于执行各种操作,如计算、转换、筛选等。
下面是一个使用BiFunction接口的示例:
import java.util.function.BiFunction;
public class Main {
public static void main(String[] args) {
// 使用BiFunction接口计算两个数的和
BiFunction<Integer, Integer, Integer> sumFunction = (a, b) -> a + b;
int sum = sumFunction.apply(5, 3);
System.out.println(sum); // 输出: 8
// 使用BiFunction接口将两个字符串拼接起来
BiFunction<String, String, String> concatenateFunction = (str1, str2) -> str1 + str2;
String result = concatenateFunction.apply("Hello, ", "World!");
System.out.println(result); // 输出: Hello, World!
}
}
BiConsumer函数接口
BiConsumer
接口,用于表示接受两个参数并执行某些操作的函数。它定义了一个名为accept(T t, U u)
的抽象方法,接受两个参数,并且没有返回值。
以下是BiConsumer接口的简化版本:
import java.util.function.BiConsumer;
@FunctionalInterface
public interface BiConsumer<T, U> {
void accept(T t, U u);
}
BiConsumer
接口适用于那些需要对传入的两个参数进行某种操作,而不需要返回结果的情况。它可以用于在不同的上下文中执行各种操作,如打印、修改状态、更新对象等。
下面是一个使用BiConsumer
接口的示例:
import java.util.function.BiConsumer;
public class Main {
public static void main(String[] args) {
// 使用BiConsumer接口打印两个数的和
BiConsumer<Integer, Integer> sumPrinter = (a, b) -> System.out.println(a + b);
sumPrinter.accept(5, 3);
// 使用BiConsumer接口打印两个字符串的拼接结果
BiConsumer<String, String> concatenationPrinter = (str1, str2) -> System.out.println(str1 + str2);
concatenationPrinter.accept("Hello, ", "World!");
}
}
那些库或中间件再用BiConsumer
BiPredicate 函数接口
BiPredicate
接口用于表示接受两个参数并返回一个布尔值的函数。它定义了一个名为test(T t, U u)的抽象方法,接受两个参数,并返回一个布尔值。
以下是BiPredicate接口的简化版本:
@FunctionalInterface
public interface BiPredicate<T, U> {
boolean test(T t, U u);
// Default methods are defined also
}
BiPredicate接口适用于那些需要对传入的两个参数进行某种条件判断,并返回布尔值的情况。它可以用于执行各种条件判断,如相等性比较、大小比较、复杂条件判断等。
下面是一个使用BiPredicate接口的示例:
import java.util.function.BiPredicate;
public class Main {
public static void main(String[] args) {
// 使用BiPredicate接口判断两个数是否相等
BiPredicate<Integer, Integer> equalityPredicate = (a, b) -> a.equals(b);
boolean isEqual = equalityPredicate.test(5, 5);
System.out.println(isEqual); // 输出: true
// 使用BiPredicate接口判断一个字符串是否包含另一个字符串
BiPredicate<String, String> containsPredicate = (str1, str2) -> str1.contains(str2);
boolean isContains = containsPredicate.test("Hello, World!", "World");
System.out.println(isContains); // 输出: true
}
}
JAVA中的函数接口,你都用过吗的更多相关文章
- 关于C++与Java中虚函数问题的读书笔记
之前一直用C++编程,对虚函数还是一些较为肤浅的理解.可近期由于某些原因搞了下Java,发现有些知识点不熟,于是站在先驱巨人的肩上谈谈C++与Java中虚函数问题. Java中的虚函数 以下是段别人的 ...
- 还不了解一下 Java 8 Predicate 函数接口
同学你好,这里有一份你的未读代码,等你查收. 这篇文章属于 Java 8 教程(LTS)系列教程,点击阅读更多相关文章. Predicate 函数接口同之前介绍的 Function 接口一样,是一个函 ...
- 用好JAVA中的函数式接口,轻松从通用代码框架中剥离掉业务定制逻辑
大家好,又见面了. 今天我们一起聊一聊JAVA中的函数式接口.那我们首先要知道啥是函数式接口.它和JAVA中普通的接口有啥区别?其实函数式接口也是一个Interface类,是一种比较特殊的接口类,这个 ...
- Java 中的集合接口——List、Set、Map
Java 中的集合接口——List.Set.Map 什么叫集合:集合就是Java API所提供的一系列类的实例,可以用于动态存放多个对象.这跟我们学过的数组差不多,那为什么我们还要学集合,我们看看数组 ...
- 转:二十一、详细解析Java中抽象类和接口的区别
转:二十一.详细解析Java中抽象类和接口的区别 http://blog.csdn.net/liujun13579/article/details/7737670 在Java语言中, abstract ...
- 关于JAVA中抽象类和接口的区别辨析
今天主要整理一下新学习的有关于Java中抽象类和接口的相关知识和个人理解. 1 抽象类 用来描述事物的一般状态和行为,然后在其子类中去实现这些状态和行为.也就是说,抽象类中的方法,需要在子类中进行重写 ...
- Java中的函数对象
初次听说java中的函数对象可能,比较的陌生.可以类比着来理解一下,人们常说java中没有了指针,殊不知,java中的对象引用就是指针,有时候我们说一个对象往往指的就是这个对象的引用,也就是说基本上把 ...
- Java中的Serializable接口和transient关键字
Java中的Serializable接口和transient关键字 Table of Contents 1. 向memcached中放数据时遇到NotSerializableException异常 2 ...
- JAVA中字符串函数subString的用法小结
本篇文章主要是对JAVA中字符串函数subString的用法进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 String str; str=str.substring(int begi ...
- java中的标记接口(标签接口)
Java中的标记接口(Marker Interface),又称标签接口(Tag Interface),具体是不包含任何方法的接口.在Java中很容易找到标记接口的例子,比如JDK中的Serialzab ...
随机推荐
- 数据库是要拿来用的,不是用来PK先进性的
周五参加了WAIC后又和一家上海本地的数据库厂商交流了一下午.等我要买高铁票回南京的时候已经买不到票了.好不容易刷到一张到苏州北的高铁票,我就上了车.上车后突然想起还不如就回苏州老家住一晚算了.到家后 ...
- Angular:error TS2717: Subsequent property declarations must have the same type. Property 'contentRect' mu st be of type 'DOMRectReadOnly', but here has type 'DOMRectReadOnly'.
解决方案 在tsconfig.json的compilerOptions选项中添加如下内容"skipLibCheck": true. 如下图所示 之后重新启动项目. 如下图启动成功
- CSS:粘性定位 使正文标题置顶
案例效果 关键代码 代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...
- pandas去重方法
原文链接:https://blog.csdn.net/missyougoon/article/details/83926840 数据去重可以使用duplicated()和drop_duplicates ...
- docker下nginx配置
一步一坑安装docker nginx 首先选择适当版本镜像下载 我选的: nginx:1.16.0 docker pull nginx:1.16.0 安装完毕之后创建挂载文件夹 : mkdir /u ...
- 文心一言 VS 讯飞星火 VS chatgpt (73)-- 算法导论7.1 4题
四.如何修改 QUICKSORT,使得它能够以非递增序进行排序? 文心一言: 快速排序(Quicksort)是一种常用的排序算法,基于分治策略进行设计.默认情况下,快速排序会以递增序进行排序.若想修改 ...
- Azure Data Factory(六)数据集类型为Dataverse的Link测试
一,引言 之前有讲过 Azure Data Factory 的 Copy Data 的操作,演示了将 Blob Storage1 的数据通过 Azure Data Factory 复制到 Blob S ...
- HiAI Foundation助力端侧音视频AI能力,高性能低功耗释放云侧成本
过去三年是端侧AI高速发展的几年,华为在2020年预言了端侧AI的发展潮流,2021年通过提供端云协同的方式使我们的HiAI Foundation应用性更进一个台阶,2022年提供视频超分端到端的解决 ...
- 解决Nginx SSL 代理 Tomcat 获取 Scheme 总是 Http 问题
背景 公司之前用的是http,但是出于苹果app审核和服务器安全性问题,要改为https,我们公司用的是沃通的ssl,按照沃通的官方文档提供的步骤完成服务器的配置. 架构上使用了 Nginx +tom ...
- WASI support in Go
原文在这里. 由 Johan Brandhorst-Satzkorn, Julien Fabre, Damian Gryski, Evan Phoenix, and Achille Roussel 发 ...