函数式接口
Java 8 在 java.util.function
包中提供了一系列函数式接口
1. Supplier 接口
特点:无参数,返回一个结果
@FunctionalInterface
public interface Supplier<T> {T get();
}
使用示例:
// 提供随机数
Supplier<Integer> randomSupplier = () -> new Random().nextInt(100);
Integer random = randomSupplier.get();// 提供当前时间
Supplier<String> timeSupplier = () -> LocalDateTime.now().toString();
String currentTime = timeSupplier.get();// 提供默认对象
Supplier<List<String>> listSupplier = ArrayList::new;
List<String> newList = listSupplier.get();
2. Predicate 接口
特点:接收一个参数,返回 boolean 值
@FunctionalInterface
public interface Predicate<T> {boolean test(T t);default Predicate<T> and(Predicate<? super T> other) {return t -> test(t) && other.test(t);}default Predicate<T> or(Predicate<? super T> other) {return t -> test(t) || other.test(t);}static <T> Predicate<T> isEqual(Object targetRef) {return null == targetRef ? Objects::isNull : object -> targetRef.equals(object);}
}
使用示例:
// 判断字符串是否为空
Predicate<String> isEmpty = str -> str == null || str.trim().isEmpty();
boolean result = isEmpty.test("hello"); // false// 组合条件
Predicate<Integer> isEven = n -> n % 2 == 0;
Predicate<Integer> isPositive = n -> n > 0;
Predicate<Integer> isEvenAndPositive = isEven.and(isPositive);boolean test = isEvenAndPositive.test(10); // true// 在导入方法中的潜在应用
Predicate<TSchoolEnterpriseCooperation> isValidTextbook = textbook -> textbook.getName() != null && !textbook.getName().trim().isEmpty();
3. BiConsumer 接口
特点:接收两个参数,不返回值
@FunctionalInterface
public interface BiConsumer<T, U> {void accept(T t, U u);default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after) {Objects.requireNonNull(after);return (l, r) -> {accept(l, r);after.accept(l, r);};}
}
使用示例:
// 操作Map
BiConsumer<String, Integer> mapPrinter = (key, value) -> System.out.println(key + ": " + value);Map<String, Integer> scores = Map.of("Alice", 90, "Bob", 85);
scores.forEach(mapPrinter);// 两个对象的操作
BiConsumer<User, Role> assignRole = (user, role) -> user.setRole(role);
4. BiFunction 接口
特点:接收两个参数,返回一个结果
@FunctionalInterface
public interface BiFunction<T, U, R> {R apply(T t, U u);default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {Objects.requireNonNull(after);return (T t, U u) -> after.apply(apply(t, u));}
}
使用示例:
// 字符串连接
BiFunction<String, String, String> concat = (str1, str2) -> str1 + " " + str2;
String result = concat.apply("Hello", "World"); // "Hello World"// 数学运算
BiFunction<Integer, Integer, Integer> multiplier = (a, b) -> a * b;
Integer product = multiplier.apply(5, 6); // 30
5. UnaryOperator 接口
特点:Function 的特例,输入和输出类型相同
@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {static <T> UnaryOperator<T> identity() {return t -> t;}
}
使用示例:
// 字符串处理
UnaryOperator<String> toUpperCase = String::toUpperCase;
String result = toUpperCase.apply("hello"); // "HELLO"// 数字处理
UnaryOperator<Integer> square = n -> n * n;
Integer squared = square.apply(5); // 25// 列表处理
UnaryOperator<List<String>> reverseList = list -> {List<String> reversed = new ArrayList<>(list);Collections.reverse(reversed);return reversed;
};
6. BinaryOperator 接口
特点:BiFunction 的特例,两个输入和输出类型相同
@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T, T, T> {static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {Objects.requireNonNull(comparator);return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;}static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {Objects.requireNonNull(comparator);return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;}
}
使用示例:
// 数学运算
BinaryOperator<Integer> adder = Integer::sum;
Integer sum = adder.apply(10, 20); // 30// 字符串连接
BinaryOperator<String> joiner = (str1, str2) -> str1 + ", " + str2;
String joined = joiner.apply("Apple", "Banana"); // "Apple, Banana"// 找最大值
BinaryOperator<Integer> max = BinaryOperator.maxBy(Integer::compare);
Integer maximum = max.apply(15, 25); // 25
7. 在导入方法中的扩展应用
使用 Predicate 进行数据验证
public <T> String importDataWithValidation(List<T> dataList,Predicate<T> validator, // 新增:数据验证Consumer<T> processor,Function<T, String> identifierProvider,boolean updateSupport) {for (T data : dataList) {try {// 先验证数据if (!validator.test(data)) {throw new ServiceException("数据验证失败");}processor.accept(data);String identifier = identifierProvider.apply(data);successMsg.append("<br/>").append(identifier).append(" 导入成功");} catch (Exception e) {// 错误处理...}}
}// 使用示例
this.importDataWithValidation(textbookList,textbook -> textbook.getName() != null && textbook.getPrice() > 0, // 验证条件this::insertTSchoolEnterpriseCooperation,cooperation -> "教材:" + cooperation.getName(),false
);
使用 Supplier 提供错误信息
public <T> String importDataWithCustomError(List<T> dataList,Consumer<T> processor,Function<T, String> identifierProvider,Supplier<String> successMessageSupplier, // 成功消息提供者Supplier<String> failureMessageSupplier) { // 失败消息提供者// ... 处理逻辑if (failureNum > 0) {throw new ServiceException(failureMessageSupplier.get() + failureMsg.toString());} else {return successMessageSupplier.get() + successMsg.toString();}
}// 使用示例
this.importDataWithCustomError(textbookList,this::insertTSchoolEnterpriseCooperation,cooperation -> "教材:" + cooperation.getName(),() -> "教材导入成功!共导入 " + successNum + " 条数据:",() -> "教材导入失败!共有 " + failureNum + " 条数据异常:"
);
8. 完整的功能接口分类
接口 | 参数 | 返回值 | 典型用途 |
---|---|---|---|
Supplier<T> | 0 | T | 数据提供、对象创建 |
Consumer<T> | 1 | void | 数据消费、操作执行 |
Function<T,R> | 1 | R | 数据转换、计算 |
Predicate<T> | 1 | boolean | 条件判断、数据验证 |
UnaryOperator<T> | 1 | T | 同类型数据转换 |
BiConsumer<T,U> | 2 | void | 双参数操作 |
BiFunction<T,U,R> | 2 | R | 双参数计算 |
BinaryOperator<T> | 2 | T | 双参数同类型计算 |
这些函数式接口让 Java 能够以更函数式的方式编写代码,提高了代码的灵活性和可复用性。