java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java8函数式接口

一文带你掌握Java8中函数式接口的使用和自定义

作者:努力的IT小胖子

函数式接口是 Java 8 引入的一种接口,用于支持函数式编程,下面我们就来深入探讨函数式接口的概念、用途以及如何创建和使用函数式接口吧

函数式接口是 Java 8 引入的一种接口,用于支持函数式编程。函数式接口通常包含一个抽象方法,可以被 Lambda 表达式或方法引用所实现。在本文中,我们将深入探讨函数式接口的概念、用途以及如何创建和使用函数式接口。

什么是函数式接口

函数式接口是只包含一个抽象方法的接口。但是默认方法和静态方法在此接口中可以定义多个。Java 中的函数式接口可以被用作 Lambda 表达式的目标类型。通过函数式接口,可以实现更简洁、更具可读性的代码,从而支持函数式编程的思想。

常见函数式接口

Java 中有一些内置的函数式接口,用于不同的用途:

自定义函数式接口

自定义函数式接口是需要在接口上添加 @FunctionalInterface 注解

定义 CustomFunctionalInterface 接口函数

@java.lang.FunctionalInterface
public interface CustomFunctionalInterface {
   void execute();
}

在上述代码中,定义了一个名为 CustomFunctionalInterface 的函数式接口,其中包含一个抽象方法 execute,这是一个无参无返回值的方法。通过使用 @FunctionalInterface 注解,明确告诉编译器这是一个函数式接口,确保它只包含一个抽象方法。

基于 CustomFunctionalInterface 使用

public class CustomFunctionInterfaceTest {
  public void test(CustomFunctionalInterface functionalInterface) {
    functionalInterface.execute();
  }
  @Test
  public void execute() {
    test(() -> System.out.println("Hello World Custom!"));
  }
}

在测试类 CustomFunctionInterfaceTest 中,定义了一个名为 test 的方法,接受一个 CustomFunctionalInterface 参数,并在方法体中调用了 execute 方法。这个方法允许将任意实现了 CustomFunctionalInterface 的 Lambda 表达式传递进来,并执行其 execute 方法。

在测试方法 execute 中,通过调用 test 方法,传递了一个 Lambda 表达式 () -> System.out.println("Hello World Custom!")。这个 Lambda 表达式实现了 CustomFunctionalInterface 的抽象方法 execute,即打印了一条 "Hello World Custom!" 的消息。

常见函数式接口基本使用

Predicate

当涉及到对集合或数据进行筛选时,Java 中的函数式接口 Predicate 可以发挥重要作用。Predicate 是一个通用的函数式接口,用于定义一个接受参数并返回布尔值的操作,用于判断条件是否满足。

Predicate 函数式接口

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

基于 Predicate 进行筛选

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class PredicateExample {
    public static List<String> filterStrings(List<String> list, Predicate<String> predicate) {
        List<String> filteredList = new ArrayList<>();
        for (String str : list) {
            if (predicate.test(str)) {
                filteredList.add(str);
            }
        }
        return filteredList;
    }
    public static void main(String[] args) {
        List<String> stringList = List.of("apple", "banana", "cherry", "date", "elderberry");
        Predicate<String> lengthPredicate = str -> str.length() > 5;
        List<String> longStrings = filterStrings(stringList, lengthPredicate);
        System.out.println("Long strings: " + longStrings);
    }
}

在这个示例中,我们定义了一个 filterStrings 方法,它接受一个字符串列表和一个 Predicate 参数,并返回符合条件的字符串列表。在 main 方法中,我们创建了一个长度判断的 Predicate,然后使用它来筛选出长度大于 5 的字符串。

Consumer

函数式接口 Consumer 在 Java 中用于表示接受一个参数并且没有返回值的操作。它可以用于执行一些对输入数据的处理,例如打印、修改等。

Consumer 函数式接口

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

基于 Consumer 进行筛选

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class ConsumerExample {
        public static void processIntegers(List<Integer> list, Consumer<Integer> consumer) {
        for (Integer num : list) {
            consumer.accept(num);
        }
    }
    public static void main(String[] args) {
        List<Integer> integerList = List.of(1, 2, 3, 4, 5);
        Consumer<Integer> squareAndPrint = num -> {
            int square = num * num;
            System.out.println("Square of " + num + " is: " + square);
        };
        processIntegers(integerList, squareAndPrint);
    }
}

在这个示例中,我们定义了一个 filterStrings 方法,它接受一个字符串列表和一个 Predicate 参数,并返回符合条件的字符串列表。在 main 方法中,我们创建了一个长度判断的 Predicate,然后使用它来筛选出长度大于 5 的字符串。

在这个示例中,我们定义了一个 processIntegers 方法,它接受一个整数列表和一个 Consumer 参数,并在方法内遍历列表,对每个元素执行 accept 方法。在 main 方法中,我们创建了一个 Consumer 实现 squareAndPrint,它会计算每个元素的平方并打印出来。

Function

函数式接口 Function 在 Java 中用于表示一个接受一个参数并产生一个结果的操作。它可以用于执行各种转换、映射和处理操作。

Function 函数式接口

Function 接口定义了一个名为 apply 的抽象方法,接受一个参数并返回一个结果。这个接口用于表示一个对输入数据的转换操作。

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

在上述定义中,T 表示输入类型,R 表示输出类型。

基于 Function 进行数据转换

转换为大写

import java.util.function.Function;
public class FunctionExample {
    public static String convertToUpperCase(String input, Function<String, String> function) {
        return function.apply(input);
    }
    public static void main(String[] args) {
        String original = "hello world";
        String upperCase = convertToUpperCase(original, str -> str.toUpperCase());
        System.out.println(upperCase);
    }
}

在这个示例中,我们定义了一个 convertToUpperCase 方法,它接受一个字符串和一个 Function 参数,用于将输入字符串转换为大写。在 main 方法中,我们通过传递一个 Function 实现来执行转换操作。

字符串长度映射

import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
public class FunctionExample {
    public static List<Integer> mapStringLengths(List<String> list, Function<String, Integer> function) {
        return list.stream()
                .map(function)
                .collect(Collectors.toList());
    }
    public static void main(String[] args) {
        List<String> strings = List.of("apple", "banana", "cherry", "date");
        List<Integer> lengths = mapStringLengths(strings, str -> str.length());
        System.out.println(lengths);
    }
}

在这个示例中,我们定义了一个 mapStringLengths 方法,它接受一个字符串列表和一个 Function 参数,用于将输入字符串映射为它们的长度。通过使用 map 操作,我们在列表中的每个字符串上执行了长度映射。

Supplier

函数式接口 Supplier 在 Java 中用于表示一个不接受参数但产生一个结果的操作。它通常用于延迟计算,只在需要时才执行操作并生成结果。

Supplier 函数式接口

Supplier 接口定义了一个名为 get 的抽象方法,用于获取一个结果。这个接口用于表示一个无参操作,只产生结果。

javaCopy code
@FunctionalInterface
public interface Supplier<T> {
    T get();
}

在上述定义中,T 表示结果的类型

基于 Supplier 进行延迟计算

随机数生成

import java.util.Random;
import java.util.function.Supplier;
public class SupplierExample {
    public static int generateRandomNumber(Supplier<Integer> supplier) {
        return supplier.get();
    }
    public static void main(String[] args) {
        Supplier<Integer> randomSupplier = () -> new Random().nextInt(100);
        int randomNumber = generateRandomNumber(randomSupplier);
        System.out.println("Random number: " + randomNumber);
    }
}

在这个示例中,我们定义了一个 generateRandomNumber 方法,它接受一个 Supplier 参数,并通过调用 get 方法获取随机数。在 main 方法中,我们创建了一个随机数生成的 Supplier,然后将它传递给 generateRandomNumber 方法来获取随机数。

延迟初始化

import java.util.function.Supplier;
public class SupplierExample {
    private String expensiveResource = null;
    public String getExpensiveResource(Supplier<String> supplier) {
        if (expensiveResource == null) {
            expensiveResource = supplier.get();
        }
        return expensiveResource;
    }
    public static void main(String[] args) {
        Supplier<String> resourceSupplier = () -> {
            System.out.println("Initializing expensive resource...");
            return "Expensive Resource";
        };
        SupplierExample example = new SupplierExample();
        System.out.println(example.getExpensiveResource(resourceSupplier));
        System.out.println(example.getExpensiveResource(resourceSupplier));
    }
}

在这个示例中,我们定义了一个 getExpensiveResource 方法,它接受一个 Supplier 参数,并使用延迟初始化的方式获取昂贵的资源。在 main 方法中,我们创建了一个资源初始化的 Supplier,然后多次调用 getExpensiveResource 方法,观察只有在需要时才会初始化资源。

到此这篇关于一文带你掌握Java8中函数式接口的使用和自定义的文章就介绍到这了,更多相关Java8函数式接口内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文