Java函数式接口使用案例
什么是函数式接口
函数式接口是只有一个抽象方法的接口,可以使用@FunctionalInterface注解标记。

核心案例:数据处理系统
// ========== 1. 自定义函数式接口 ==========
@FunctionalInterface
interface DataTransformer<T, R> {
R transform(T data);
// 默认方法不是抽象方法,不影响函数式接口定义
default void log(String message) {
System.out.println("[Log] " + message);
}
}
// ========== 2. 使用Java内置函数式接口 ==========
import java.util.function.*;
import java.util.*;
public class FunctionalInterfaceDemo {
public static void main(String[] args) {
// 案例1:Predicate - 条件判断
System.out.println("=== Predicate 案例 ===");
Predicate<Integer> isPositive = n -> n > 0;
Predicate<Integer> isEven = n -> n % 2 == 0;
System.out.println("5是正数吗?" + isPositive.test(5));
System.out.println("6是正数且是偶数吗?" + isPositive.and(isEven).test(6));
// 案例2:Function - 转换数据
System.out.println("\n=== Function 案例 ===");
Function<String, Integer> strToLength = String::length;
Function<Integer, String> intToStr = Object::toString;
// 方法链:先转长度,再转字符串
String result = strToLength.andThen(intToStr).apply("Hello World");
System.out.println("字符串长度转换结果:" + result);
// 案例3:Consumer - 消费数据
System.out.println("\n=== Consumer 案例 ===");
Consumer<String> printUpperCase = str ->
System.out.println(str.toUpperCase());
Consumer<String> printLength = str ->
System.out.println("长度: " + str.length());
// 链式调用
printUpperCase.andThen(printLength).accept("functional");
// 案例4:Supplier - 提供数据
System.out.println("\n=== Supplier 案例 ===");
Supplier<Double> randomSupplier = Math::random;
System.out.println("随机数: " + randomSupplier.get());
System.out.println("随机数: " + randomSupplier.get());
// 案例5:自定义函数式接口使用
System.out.println("\n=== 自定义函数式接口案例 ===");
DataTransformer<String, String> encrypt = data -> {
StringBuilder sb = new StringBuilder();
for (char c : data.toCharArray()) {
sb.append((char)(c + 1)); // 简单的加密
}
return sb.toString();
};
String original = "Hello";
String encrypted = encrypt.transform(original);
System.out.println("原始: " + original);
System.out.println("加密: " + encrypted);
}
}
// ========== 3. 实际业务场景:订单处理系统 ==========
class OrderProcessor {
// 使用函数式接口处理订单
public static <T> List<T> processOrders(
List<T> orders,
Predicate<T> filter,
Function<T, T> transformer,
Consumer<T> action) {
List<T> result = new ArrayList<>();
for (T order : orders) {
// 1. 过滤
if (!filter.test(order)) continue;
// 2. 转换
T transformed = transformer.apply(order);
// 3. 执行操作
action.accept(transformed);
result.add(transformed);
}
return result;
}
// 测试代码
public static void main(String[] args) {
List<String> orders = Arrays.asList("ORD-1001", "ORD-1002", "ORD-1003");
// 使用Lambda表达式定义处理逻辑
List<String> processed = processOrders(
orders,
order -> order.startsWith("ORD-"), // 过滤条件
order -> order.replace("ORD-", ""), // 转换格式
order -> System.out.println("处理订单: " + order) // 输出结果
);
System.out.println("处理结果: " + processed);
}
}
// ========== 4. 策略模式与函数式接口 ==========
class PaymentStrategy {
// 支付接口作为函数式接口
@FunctionalInterface
interface Payment {
void pay(double amount);
}
public static void main(String[] args) {
// 定义不同的支付策略
Payment creditCard = amount ->
System.out.printf("信用卡支付: %.2f元%n", amount);
Payment alipay = amount ->
System.out.printf("支付宝支付: %.2f元%n", amount);
Payment wechat = amount ->
System.out.printf("微信支付: %.2f元%n", amount);
// 执行支付
double price = 99.99;
System.out.println("--- 支付演示 ---");
creditCard.pay(price);
alipay.pay(price);
wechat.pay(price);
}
}
Java 8+ 常用函数式接口总结
| 接口 | 参数 | 返回值 | 使用场景 |
|---|---|---|---|
Predicate<T> |
T | boolean | 条件判断、过滤 |
Function<T,R> |
T | R | 数据转换 |
Consumer<T> |
T | void | 遍历操作、打印 |
Supplier<T> |
无 | T | 工厂方法、延迟计算 |
UnaryOperator<T> |
T | T | 相同类型转换 |
BinaryOperator<T> |
T,T | T | 合并两个同类型数据 |
高级应用:方法引用
import java.util.*;
import java.util.stream.*;
class MethodReferenceDemo {
static class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
static int compareByAge(Person a, Person b) {
return a.age - b.age;
}
@Override
public String toString() {
return name + "(" + age + ")";
}
}
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", 25),
new Person("Bob", 20),
new Person("Charlie", 30)
);
// 方法引用:静态方法
people.sort(Person::compareByAge);
System.out.println("按年龄排序: " + people);
// 方法引用:实例方法
people.forEach(System.out::println);
// 方法引用:构造函数
Supplier<Person> personFactory = Person::new;
}
}
使用建议
- 优先使用内置函数式接口,避免自定义
- Lambda表达式 + 方法引用 是最佳实践
- 配合Stream API 使用效果最佳
- 注意变量捕获:Lambda中使用的局部变量必须是final或effectively final