常用函数式接口

生产型接口Supplier

简述

该函数接口是Java8中的java.util.function 包中的。包含一个get()

作用

  • 延迟计算:
    在需要时才生成值,提高效率。

  • 简化代码:
    封装生成逻辑,避免重复代码。

  • 灵活性:
    可以与其他函数式接口结合使用,增强可组合性。

  • 无输入参数:
    专注于提供结果,适用于无状态的生成逻辑。

代码案例

import java.util.List;
import java.util.ArrayList;
import java.util.Random;
import java.util.function.Supplier;

class User {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{name='" + name + "', age=" + age + "}";
    }
}

public class SupplierFeaturesExample {

    private static final String[] NAMES = {"Alice", "Bob", "Charlie", "Diana", "Eve"};
    private static final Random RANDOM = new Random();

    public static void main(String[] args) {
        // Supplier 用于生成随机用户
        Supplier<User> userSupplier = () -> {
            String name = NAMES[RANDOM.nextInt(NAMES.length)];
            int age = RANDOM.nextInt(50) + 18; // 生成 18 到 67 之间的随机年龄
            return new User(name, age);
        };

        // 延迟计算:用户信息在需要时才生成
        List<User> userList = new ArrayList<>();
        System.out.println("Generating random users...");

        for (int i = 0; i < 5; i++) {
            // 每次调用 userSupplier.get() 都会生成一个新的随机用户
            User user = userSupplier.get();
            userList.add(user);
            System.out.println("Generated user: " + user);
        }

        // 使用 Supplier 生成用户的另一种方式:将 Supplier 作为参数传递
        List<User> moreUsers = generateUsers(() -> {
            String name = NAMES[RANDOM.nextInt(NAMES.length)];
            int age = RANDOM.nextInt(50) + 18;
            return new User(name, age);
        }, 5);

        System.out.println("\nAdditional generated users:");
        moreUsers.forEach(System.out::println);
    }

    // 接受 Supplier 的方法,生成指定数量的用户
    private static List<User> generateUsers(Supplier<User> userSupplier, int count) {
        List<User> users = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            users.add(userSupplier.get());
        }
        return users;
    }
}

消费型接口Consumer

简述

Consumer 接口是 Java 8 引入的一个函数式接口,位于 java.util.function 包中。它代表一个接受单个输入参数并且没有返回结果的操作。Consumer 通常用于处理某种类型的对象,比如打印、修改或存储数据。

作用

  • 处理数据:
    Consumer 可以用于对单个输入数据进行处理,如打印、修改或存储。这使得数据处理逻辑能够被清晰地定义。

  • 简化代码:
    通过使用 Consumer,可以减少样板代码,使得操作更加简洁。例如,可以直接在集合的 forEach 方法中传入 Consumer 实现,从而避免显式的循环。

  • 函数式编程支持:
    Consumer 支持函数式编程风格,使得开发者能够以更灵活的方式组合和传递行为。例如,可以将多个 Consumer 组合在一起,通过 andThen 方法实现链式调用。

  • 事件处理:
    在事件驱动编程中,Consumer 可以用于处理用户输入或其他事件,提供了一种清晰的方式来定义事件处理逻辑。

  • 增强可读性:
    使用 Consumer 可以使代码逻辑更加清晰易懂,特别是在进行集合操作时,能让操作意图一目了然。

代码案例

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

        // 定义一个 Consumer,打印每个名字
        Consumer<String> printName = name -> System.out.println(name);

        // 使用 forEach 方法与 Consumer
        names.forEach(printName);

        // 使用 andThen 方法,打印名字并附加额外操作
        names.forEach(printName.andThen(name -> System.out.println("Length: " + name.length())));
    }
}

判断型接口Predicate

简述

Predicate 接口是 Java 8 引入的一个函数式接口,属于 java.util.function 包。它用于测试输入值是否满足某种条件,并返回一个布尔值。Predicate 主要用于过滤和判断操作

作用

  • 过滤集合:
    在处理集合数据时,可以使用 Predicate 进行条件过滤。

  • 条件判断:
    可以使用 Predicate 来判断对象是否符合某些条件,用于实现业务逻辑。

  • 流操作:
    在 Java Streams API 中,Predicate 被广泛用于过滤流中的元素。

代码案例

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class PredicateExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");

        // 定义一个 Predicate,判断名字是否以字母 'A' 开头
        Predicate<String> startsWithA = name -> name.startsWith("A");

        // 过滤集合中符合条件的名字
        List<String> filteredNames = names.stream()
                                          .filter(startsWithA)
                                          .collect(Collectors.toList());

        System.out.println(filteredNames); // 输出: [Alice]

        // 使用 and 方法,判断名字是否以字母 'A' 开头并且长度大于 3
        Predicate<String> startsWithAAndLongerThan3 = startsWithA.and(name -> name.length() > 3);
        filteredNames = names.stream()
                             .filter(startsWithAAndLongerThan3)
                             .collect(Collectors.toList());

        System.out.println(filteredNames); // 输出: [Alice]

        // 使用 or 方法,判断名字是否以字母 'A' 开头或名字长度大于 5
        Predicate<String> startsWithAOrLongerThan5 = startsWithA.or(name -> name.length() > 5);
        filteredNames = names.stream()
                             .filter(startsWithAOrLongerThan5)
                             .collect(Collectors.toList());

        System.out.println(filteredNames); // 输出: [Alice, Charlie]
        
        // 使用 negate 方法,判断名字是否不以字母 'A' 开头
        Predicate<String> notStartsWithA = startsWithA.negate();
        filteredNames = names.stream()
                             .filter(notStartsWithA)
                             .collect(Collectors.toList());

        System.out.println(filteredNames); // 输出: [Bob, Charlie, David]
    }
}

转换型接口Function

简述

Function 接口是 Java 8 引入的一个函数式接口,属于 java.util.function 包。它代表了一个接受一个输入参数并生成一个输出结果的函数。Function 接口的主要作用是将一个输入值转换成另一个值,因此常用于数据转换和映射操作中。

作用

  • 数据转换:
    用于将数据从一种形式转换为另一种形式。

  • 集合操作:
    在处理集合数据时,可以使用 Function 来映射集合中的元素。

  • 流操作:
    在 Java Streams API 中,Function 被广泛用于将流中的元素映射到另一个形式。

代码案例

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class FunctionExample {
    public static void main(String[] args) {
        // 定义一个 Function,将字符串转换为其长度
        Function<String, Integer> stringLengthFunction = String::length;

        // 使用 Function 计算每个名字的长度
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
        List<Integer> nameLengths = names.stream()
                                         .map(stringLengthFunction)
                                         .collect(Collectors.toList());

        System.out.println(nameLengths); // 输出: [5, 3, 7, 5]

        // 定义一个 Function,将整数转换为其平方
        Function<Integer, Integer> squareFunction = x -> x * x;

        // 组合两个 Function:首先计算字符串的长度,然后计算长度的平方
        Function<String, Integer> lengthSquaredFunction = stringLengthFunction.andThen(squareFunction);
        List<Integer> lengthSquares = names.stream()
                                           .map(lengthSquaredFunction)
                                           .collect(Collectors.toList());

        System.out.println(lengthSquares); // 输出: [25, 9, 49, 25]

        // 组合两个 Function:首先计算字符串的长度,然后计算长度加 1
        Function<String, Integer> lengthPlusOneFunction = stringLengthFunction.compose(x -> x + "X");
        List<Integer> lengthPlusOne = names.stream()
                                           .map(lengthPlusOneFunction)
                                           .collect(Collectors.toList());

        System.out.println(lengthPlusOne); // 输出: [6, 4, 8, 6]
    }
}
posted @   DAawson  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示