Java 函数式接口:Supplier 和 Consumer 使用示例
·
Java 函数式接口:Supplier 和 Consumer 使用示例
Supplier 和 Consumer 是 Java 8 中引入的两个核心函数式接口,它们分别代表"生产者"和"消费者"的概念。下面我将通过几个实用的示例来展示它们的使用方法。
1. 基础概念
- Supplier: 无参数,返回一个结果。方法签名:
T get() - Consumer: 接受一个参数,不返回结果。方法签名:
void accept(T t)
2. 基本使用示例
Supplier 示例
import java.util.function.Supplier;
import java.time.LocalDateTime;
import java.util.Random;
public class SupplierDemo {
public static void main(String[] args) {
// 示例1: 获取当前时间
Supplier<LocalDateTime> currentTimeSupplier = () -> LocalDateTime.now();
System.out.println("当前时间: " + currentTimeSupplier.get());
// 示例2: 生成随机数
Supplier<Integer> randomSupplier = () -> new Random().nextInt(100);
System.out.println("随机数: " + randomSupplier.get());
// 示例3: 延迟初始化(懒加载)
Supplier<ExpensiveObject> expensiveObjectSupplier = () -> {
System.out.println("创建昂贵对象...");
return new ExpensiveObject();
};
System.out.println("Supplier创建了,但对象尚未初始化");
// 只有当调用get()时,对象才会被创建
ExpensiveObject obj = expensiveObjectSupplier.get();
}
static class ExpensiveObject {
ExpensiveObject() {
// 模拟耗时操作
try { Thread.sleep(1000); } catch (InterruptedException e) {}
}
}
}
Consumer 示例
import java.util.function.Consumer;
import java.util.Arrays;
import java.util.List;
public class ConsumerDemo {
public static void main(String[] args) {
// 示例1: 简单消费
Consumer<String> printConsumer = s -> System.out.println(s);
printConsumer.accept("Hello, Consumer!");
// 示例2: 集合遍历
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(printConsumer);
// 示例3: 链式操作
Consumer<String> upperCaseConsumer = s -> System.out.println(s.toUpperCase());
Consumer<String> decoratedConsumer = s -> System.out.println("*** " + s + " ***");
// 使用andThen组合多个Consumer
Consumer<String> combinedConsumer = printConsumer.andThen(upperCaseConsumer).andThen(decoratedConsumer);
combinedConsumer.accept("Functional Interface");
}
}
3. 实际应用场景
场景1: 日志记录
import java.util.function.Supplier;
import java.util.function.Consumer;
public class LoggerExample {
// 使用Supplier延迟日志消息的计算(只有在需要记录时才计算)
public static void logIfNeeded(boolean condition, Supplier<String> messageSupplier) {
if (condition) {
System.out.println(messageSupplier.get());
}
}
// 使用Consumer处理日志输出(可以灵活替换输出方式)
public static void processWithLogging(String data, Consumer<String> logger) {
logger.accept("开始处理: " + data);
// 处理逻辑...
logger.accept("处理完成: " + data);
}
public static void main(String[] args) {
// 只有在需要记录时才构建复杂的日志消息
logIfNeeded(true, () -> "这是一个复杂的日志消息: " + System.currentTimeMillis());
// 可以灵活切换日志输出方式
Consumer<String> consoleLogger = System.out::println;
Consumer<String> fileLogger = message -> {
// 这里简化实现,实际中会写入文件
System.out.println("写入文件: " + message);
};
processWithLogging("测试数据", consoleLogger);
processWithLogging("重要数据", fileLogger);
}
}
场景2: 数据验证和处理
import java.util.function.Consumer;
import java.util.ArrayList;
import java.util.List;
public class ValidationExample {
public static void main(String[] args) {
List<String> emails = new ArrayList<>();
emails.add("valid@example.com");
emails.add("invalid-email");
emails.add("another@test.com");
// 定义不同的处理器
Consumer<String> emailValidator = email -> {
if (!email.contains("@")) {
System.out.println("无效邮箱: " + email);
}
};
Consumer<String> emailProcessor = email -> {
if (email.contains("@")) {
System.out.println("处理邮箱: " + email);
}
};
// 组合使用
Consumer<String> emailHandler = emailValidator.andThen(emailProcessor);
// 处理所有邮箱
emails.forEach(emailHandler);
}
}
场景3: 资源管理
import java.util.function.Consumer;
import java.util.function.Supplier;
public class ResourceManager {
// 使用Supplier提供资源,Consumer处理资源
public static <T> void withResource(Supplier<T> resourceSupplier, Consumer<T> resourceConsumer) {
T resource = resourceSupplier.get();
try {
resourceConsumer.accept(resource);
} finally {
// 这里简化实现,实际中可能需要关闭资源
System.out.println("清理资源: " + resource.getClass().getSimpleName());
}
}
public static void main(String[] args) {
// 模拟数据库连接
Supplier<DatabaseConnection> dbConnectionSupplier = () -> {
System.out.println("建立数据库连接...");
return new DatabaseConnection();
};
Consumer<DatabaseConnection> dbQuery = connection -> {
System.out.println("执行查询...");
// 实际查询操作...
};
// 自动管理资源
withResource(dbConnectionSupplier, dbQuery);
}
static class DatabaseConnection {
// 模拟数据库连接
}
}
场景4: 配置灵活的业务流程
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.List;
import java.util.ArrayList;
public class OrderProcessor {
public static void main(String[] args) {
// 定义订单创建器
Supplier<Order> orderSupplier = () -> new Order("ORD-001", 100.0);
// 定义不同的订单处理器
List<Consumer<Order>> processors = new ArrayList<>();
processors.add(order -> order.applyDiscount(0.1)); // 打9折
processors.add(order -> order.addTax(0.08)); // 加8%税
processors.add(order -> System.out.println("订单处理完成: " + order));
// 处理订单
Order order = orderSupplier.get();
processors.forEach(processor -> processor.accept(order));
}
static class Order {
private String id;
private double amount;
public Order(String id, double amount) {
this.id = id;
this.amount = amount;
}
public void applyDiscount(double rate) {
this.amount *= (1 - rate);
System.out.println("应用折扣: " + (rate * 100) + "%");
}
public void addTax(double rate) {
this.amount *= (1 + rate);
System.out.println("添加税费: " + (rate * 100) + "%");
}
@Override
public String toString() {
return "Order{id='" + id + "', amount=" + amount + "}";
}
}
}
4. 高级用法:组合与柯里化
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.function.Function;
public class AdvancedExamples {
public static void main(String[] args) {
// 组合多个Consumer
Consumer<String> logStep1 = s -> System.out.println("步骤1: " + s);
Consumer<String> logStep2 = s -> System.out.println("步骤2: " + s);
Consumer<String> logStep3 = s -> System.out.println("步骤3: " + s);
Consumer<String> fullProcess = logStep1.andThen(logStep2).andThen(logStep3);
fullProcess.accept("处理数据");
// 使用Supplier和Function创建处理管道
Supplier<String> dataSupplier = () -> "原始数据";
Function<String, String> step1 = s -> s + " -> 步骤1处理";
Function<String, String> step2 = s -> s + " -> 步骤2处理";
Function<String, String> step3 = s -> s + " -> 步骤3处理";
String result = step1.andThen(step2).andThen(step3).apply(dataSupplier.get());
System.out.println("最终结果: " + result);
}
}
总结
Supplier 和 Consumer 接口的主要优势:
- 延迟执行:Supplier 可以延迟计算,直到真正需要结果时才执行
- 代码解耦:将数据的生产(Supplier)和消费(Consumer)分离
- 灵活性:可以轻松替换不同的实现,而不需要修改主要逻辑
- 组合性:通过
andThen方法可以轻松组合多个操作
在实际开发中,合理使用这些函数式接口可以使代码更加简洁、灵活和可维护。
更多推荐


所有评论(0)