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 函数式编程的基础,让代码更加简洁、可读性强,并支持链式调用和组合使用。

浙公网安备 33010602011771号