函数式接口

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>0T数据提供、对象创建
Consumer<T>1void数据消费、操作执行
Function<T,R>1R数据转换、计算
Predicate<T>1boolean条件判断、数据验证
UnaryOperator<T>1T同类型数据转换
BiConsumer<T,U>2void双参数操作
BiFunction<T,U,R>2R双参数计算
BinaryOperator<T>2T双参数同类型计算

这些函数式接口让 Java 能够以更函数式的方式编写代码,提高了代码的灵活性和可复用性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值