0

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

 8 months ago
source link: https://www.51cto.com/article/777359.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

作者:蜗牛 2023-12-22 16:39:47
只包含一个抽象方法的接口称为函数式接口,在这篇文章中,我们将通过示例来学习 Java 函数式接口。

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

一、函数式接口的特点

  • 只包含一个抽象方法的接口称为函数式接口。
  • 它可以有任意数量的默认静态方法,但只能包含一个抽象方法。它还可以声明对象类的方法。
  • 函数接口也称为单一抽象方法接口或SAM 接口。
  • 函数式接口只有在没有任何抽象方法时才可以扩展另一个接口。
  • Java API 具有许多单方法接口,例如 Runnable、Callable、Comparator、ActionListener等。它们可以使用匿名类语法来实现和实例化。
69550e4537d85b70d9d257964f852d2e855516.jpg

二、接口示例

创建一个自定义的Sayable接口,这是一个使用@FunctionalInterface注解的函数式接口。@FunctionalInterface注解表示该接口是一个函数式接口,并且只包含一个抽象方法。

1.自定义函数接口示例:

@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 ..");
    }
}

2.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);
            }
        }
    }
}

3.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
    }
}

4.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);
    }
}

5.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接口的使用场景包括遍历集合、处理回调函数、更新对象状态等。它提供了一种简洁的方式来执行针对输入参数的操作,使得代码更加清晰和模块化。

6.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!
    }
}

7.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!");
    }
}

8.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
    }
}
责任编辑:赵宁宁 来源: 架构成长指南

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK