java函数接口介绍

 

Supplier(供应者)

概念:不接收任何输入参数,但会返回一个指定类型的值。就像一个"供应商",可以随时提供某种类型的对象。

示例

import java.time.LocalDateTime;
import java.util.function.Supplier;
import java.util.Random;

// 1. 提供字符串
Supplier<String> greetingSupplier = () -> "你好,世界!";
System.out.println(greetingSupplier.get()); // 输出: 你好,世界!

// 2. 提供随机数
Supplier<Integer> randomSupplier = () -> new Random().nextInt(100);
System.out.println(randomSupplier.get()); // 输出: 0-99之间的随机数

// 3. 提供当前时间
Supplier<LocalDateTime> timeSupplier = () -> LocalDateTime.now();
System.out.println(timeSupplier.get()); // 输出: 当前时间,如 2025-12-03T10:30:45.123

// 4. 在您的项目中的实际应用 - 延迟创建异常对象
Supplier<BasicServiceException> exceptionSupplier = () -> 
    new BasicServiceException("新增职位失败,请稍后再试!");

// 只有在获取锁失败时才创建异常对象,避免不必要的对象创建开销
// if (lockFailed) {
//     throw exceptionSupplier.get(); // 这时才真正创建异常对象
// }

Consumer(消费者)

概念:接收一个输入参数,但不返回任何值。就像一个"消费者",消费掉传入的数据。

示例

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

// 1. 简单的打印消费者
Consumer<String> printer = (str) -> System.out.println("打印内容: " + str);
printer.accept("Hello World"); // 输出: 打印内容: Hello World

// 2. 处理数字
Consumer<Integer> numberProcessor = (num) -> {
    System.out.println("接收到数字: " + num);
    System.out.println("平方值: " + (num * num));
};
numberProcessor.accept(5); 
// 输出: 
// 接收到数字: 5
// 平方值: 25

// 3. 在集合遍历中的应用
List<String> names = Arrays.asList("张三", "李四", "王五");
Consumer<String> nameHandler = (name) -> {
    System.out.println("处理员工: " + name);
    // 可以进行更多复杂的处理,比如保存到数据库等
};

// forEach 方法内部就是使用 Consumer
names.forEach(nameHandler);
// 输出:
// 处理员工: 张三
// 处理员工: 李四
// 处理员工: 王五

// 4. 复杂对象处理
Consumer<Account> accountProcessor = (account) -> {
    System.out.println("处理账户: " + account.getAcctName());
    // 更新账户状态
    account.setAcctStatus("ACTIVE");
    // 发送通知等其他业务逻辑
};

Function<T,R>(函数)

概念:接收一个类型为 T 的参数,返回一个类型为 R 的结果。用于将一种类型的数据转换为另一种类型。

示例

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

// 1. 字符串长度计算
Function<String, Integer> strLength = (str) -> str.length();
int length = strLength.apply("Hello"); // 返回 5

// 2. 字符串转大写
Function<String, String> toUpperCase = (str) -> str.toUpperCase();
String upper = toUpperCase.apply("hello"); // 返回 "HELLO"

// 3. 数字运算
Function<Integer, Integer> square = (num) -> num * num;
int result = square.apply(4); // 返回 16

// 4. 对象转换
Function<Account, String> accountNameExtractor = (account) -> account.getAcctName();
// 或者使用方法引用
Function<Account, String> accountNameExtractor2 = Account::getAcctName;

// 5. 在Stream中的应用
List<String> words = Arrays.asList("apple", "banana", "cherry");
List<Integer> wordLengths = words.stream()
    .map(strLength) // 使用Function进行转换
    .collect(Collectors.toList()); // 结果: [5, 6, 6]

// 6. 复杂对象映射
Function<Account, AccountVO> accountConverter = (account) -> {
    AccountVO vo = new AccountVO();
    vo.setName(account.getAcctName());
    vo.setCode(account.getAcctCode());
    vo.setStatus(account.getAcctStatus());
    return vo;
};

Predicate(谓词)

概念:接收一个类型为 T 的参数,返回 boolean 类型的结果。用于判断某个条件是否成立。

示例

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

// 1. 简单的数值判断
Predicate<Integer> isEven = (num) -> num % 2 == 0;
boolean result = isEven.test(4); // 返回 true
System.out.println(isEven.test(3)); // 返回 false

// 2. 字符串判断
Predicate<String> isEmpty = (str) -> str == null || str.isEmpty();
System.out.println(isEmpty.test("")); // 返回 true
System.out.println(isEmpty.test("Hello")); // 返回 false

// 3. 对象属性判断
Predicate<Account> isActiveAccount = (account) -> 
    "Y".equals(account.getAcctStatus());
    
Predicate<Account> isVIPAccount = (account) -> 
    account.getAccountLevel() != null && account.getAccountLevel() >= 5;

// 4. 组合判断
Predicate<Account> activeVIPAccount = isActiveAccount.and(isVIPAccount);
Predicate<Account> inactiveAccount = isActiveAccount.negate(); // 取反

// 5. 在Stream中的应用
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> evenNumbers = numbers.stream()
    .filter(isEven) // 使用Predicate进行过滤
    .collect(Collectors.toList()); // 结果: [2, 4, 6, 8, 10]

// 6. 复杂业务场景
List<Account> accounts = getAccounts(); // 假设有账户列表

// 筛选活跃的VIP客户
List<Account> activeVIPAccounts = accounts.stream()
    .filter(activeVIPAccount)
    .collect(Collectors.toList());

// 筛选即将到期的账户
Predicate<Account> expiringSoon = (account) -> {
    if (account.getExpiryDate() == null) return false;
    LocalDate expiry = account.getExpiryDate().toInstant()
        .atZone(ZoneId.systemDefault()).toLocalDate();
    LocalDate now = LocalDate.now();
    return expiry.isAfter(now) && expiry.isBefore(now.plusDays(30));
};

组合使用

// 综合示例:处理员工数据
List<Employee> employees = Arrays.asList(
    new Employee("张三", 25, 8000),
    new Employee("李四", 30, 12000),
    new Employee("王五", 28, 9500),
    new Employee("赵六", 35, 15000)
);

// 定义各种函数式接口
Predicate<Employee> highSalary = emp -> emp.getSalary() > 10000; // 高薪员工
Function<Employee, String> nameExtractor = Employee::getName;     // 提取姓名
Consumer<String> namePrinter = name -> System.out.println("高薪员工: " + name);
Supplier<List<Employee>> emptyList = ArrayList::new;             // 提供空列表

// 组合使用
employees.stream()
    .filter(highSalary)           // 使用 Predicate 过滤
    .map(nameExtractor)           // 使用 Function 转换
    .forEach(namePrinter);        // 使用 Consumer 处理

// 输出:
// 高薪员工: 李四
// 高薪员工: 赵六

// 在锁机制中的实际应用
public class LockExample {
    private LockTemplate lockTemplate;
    
    public void insertPosition(Position position) {
        String lockName = "position_insert_lock";
        
        // Supplier 用于延迟创建异常
        Supplier<BasicServiceException> exceptionSupplier = 
            () -> new BasicServiceException("系统繁忙,请稍后再试!");
            
        // Supplier 用于提供实际业务逻辑
        Supplier<Map<String, Object>> businessLogic = 
            () -> performInsert(position);
            
        // 只有获取锁成功才执行 businessLogic,失败则通过 exceptionSupplier 创建异常
        lockTemplate.lockWithResult(
            exceptionSupplier, 
            lockName, 
            5, 10, TimeUnit.SECONDS, 
            businessLogic
        );
    }
    
    private Map<String, Object> performInsert(Position position) {
        // 实际的插入逻辑
        return super.insert(position);
    }
}

总结对比

接口 参数 返回值 典型用途 实际应用场景
Supplier T 提供数据 延迟创建对象、工厂模式
Consumer T 消费处理 日志打印、数据保存、副作用操作
Function<T,R> T R 数据转换 类型映射、对象转换、计算
Predicate T boolean 条件判断 过滤、验证、条件检查

这四种函数式接口构成了 Java 函数式编程的基础,让代码更加简洁、可读性强,并支持链式调用和组合使用。

 

posted @ 2025-12-03 10:34  叶璃溪  阅读(2)  评论(0)    收藏  举报
Live2D