写点什么

JAVA 中的函数接口,你都用过吗

  • 2023-11-20
    福建
  • 本文字数:4729 字

    阅读完需:约 16 分钟

在这篇文章中,我们将通过示例来学习 Java 函数式接口。


函数式接口的特点


  1. 只包含一个抽象方法的接口称为函数式接口。


  1. 它可以有任意数量的默认静态方法,但只能包含一个抽象方法。它还可以声明对象类的方法。


  1. 函数接口也称为单一抽象方法接口或 SAM 接口。


  1. 函数式接口只有在没有任何抽象方法时才可以扩展另一个接口。


  1. 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 中的一个函数式接口,它定义了一个接收一个参数并返回结果的函数。它的定义如下:


@FunctionalInterfacepublic 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 接口的实现


@FunctionalInterfacepublic 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 接口的简化版本


@FunctionalInterfacepublic 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接口的简化版本。


@FunctionalInterfacepublic 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;
@FunctionalInterfacepublic 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 }}
复制代码


文章转载自:架构成长指南

原文链接:https://www.cnblogs.com/waldron/p/17841836.html

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
JAVA中的函数接口,你都用过吗_Java_不在线第一只蜗牛_InfoQ写作社区