You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Java泛型合并Spring Boot中两个CsvToBeanFilter实现类?

用Java泛型合并CsvToBeanFilter实现的方案

你完全可以用一个泛型类替代两个重复实现,核心是把类型转换逻辑和过滤逻辑解耦,让泛型参数适配不同的数据类型。不需要抽象类,直接一个泛型实现类就能搞定,代码复用性更高。

实现思路

  1. 泛型类GenericContainsFilter<T>实现CsvToBeanFilter,泛型T表示要匹配的目标数据类型(Integer/String等)
  2. 类内维护三个核心属性:
    • 要检查的CSV列索引
    • 目标匹配列表(List<T>)
    • 类型转换器(Function<String, T>):负责把CSV读取到的字符串转成目标类型T
  3. 在allowLine方法里,统一执行「取列值→转类型→判断是否在目标列表」的逻辑

完整代码实现

import com.opencsv.bean.CsvToBeanFilter;
import java.util.List;
import java.util.function.Function;

public class GenericContainsFilter<T> implements CsvToBeanFilter {
    private final int targetIndex;
    private final List<T> targetList;
    private final Function<String, T> typeConverter;

    // 构造方法,接收核心参数
    public GenericContainsFilter(int targetIndex, List<T> targetList, Function<String, T> typeConverter) {
        this.targetIndex = targetIndex;
        this.targetList = targetList;
        this.typeConverter = typeConverter;
    }

    @Override
    public boolean allowLine(String[] line) {
        // 边界校验:索引越界直接返回false(可根据业务调整)
        if (targetIndex < 0 || targetIndex >= line.length) {
            return false;
        }
        try {
            // 转换CSV字符串为目标类型,判断是否在列表中
            T value = typeConverter.apply(line[targetIndex]);
            return targetList.contains(value);
        } catch (Exception e) {
            // 类型转换失败时的处理,比如返回false或抛出异常,按需调整
            return false;
        }
    }

    // 静态工厂方法,简化常用类型的实例创建(可选,但更易用)
    public static GenericContainsFilter<Integer> forInteger(int index, List<Integer> targetList) {
        return new GenericContainsFilter<>(index, targetList, Integer::valueOf);
    }

    public static GenericContainsFilter<String> forString(int index, List<String> targetList) {
        // String类型不需要转换,直接返回原字符串
        return new GenericContainsFilter<>(index, targetList, s -> s);
    }
}

使用示例

// 替代原ContainsIntegerFilter的用法
List<Integer> integerTargets = List.of(100, 200, 300);
GenericContainsFilter<Integer> integerFilter = GenericContainsFilter.forInteger(2, integerTargets);

// 替代原ContainsStringFilter的用法
List<String> stringTargets = List.of("admin", "user", "guest");
GenericContainsFilter<String> stringFilter = GenericContainsFilter.forString(0, stringTargets);

为什么不需要抽象类?

你的抽象类方案可能会引入不必要的层级,因为这里的差异仅在于类型转换逻辑,核心过滤逻辑完全一致。用泛型+函数式接口(Function)已经足够把差异点抽离,代码更简洁,复用性更强。如果后续需要支持其他类型(比如Long、Double),只需要新增对应的静态工厂方法,或者直接传入自定义转换器即可。

内容的提问来源于stack exchange,提问作者Jack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 17:40:31