✅ 核心挑战
- 类型不安全:直接强转可能抛出 ClassCastException
- null 值干扰:null无法判断类型
- 数字类型混淆:Integer、Long、Double如何统一处理?
- 可维护性差:if-else堆砌,代码难以扩展
✅ 策略一:使用 instanceof 进行类型过滤(基础但可靠)
需求:从 List<Object> 中提取所有字符串。
实现:
List<Object> mixed = ... // 混合数据
List<String> strings = mixed.stream()
    .filter(Objects::nonNull)
    .filter(item -> item instanceof String)
    .map(item -> (String) item)
    .collect(Collectors.toList());✅ 提取所有数字(Integer, Long, Double 等)
List<Number> numbers = mixed.stream()
    .filter(Objects::nonNull)
    .filter(item -> item instanceof Number)
    .map(item -> (Number) item)
    .collect(Collectors.toList());✅ Number 是 Integer、Long、Double 等的父类,可统一处理。
✅ 策略二:按“语义类型”分组过滤(高级分类)
需求:将混合数据按“字符串、数字、布尔、其他”分类。
实现:
Map<String, List<Object>> grouped = mixed.stream()
    .filter(Objects::nonNull)
    .collect(Collectors.groupingBy(item -> {
        if (item instanceof String) return "string";
        else if (item instanceof Number) return "number";
        else if (item instanceof Boolean) return "boolean";
        else return "other";
    }));
// 使用
List<Object> strings = grouped.get("string");
List<Object> numbers = grouped.get("number");✅ 封装为通用分类器
public enum DataType {
    STRING, NUMBER, BOOLEAN, DATE, OTHER;
    public static DataType of(Object value) {
        if (value == null) return OTHER;
        if (value instanceof String) return STRING;
        if (value instanceof Number) return NUMBER;
        if (value instanceof Boolean) return BOOLEAN;
        if (value instanceof LocalDate || value instanceof Instant) return DATE;
        return OTHER;
    }
}
// 使用
Map<DataType, List<Object>> classified = mixed.stream()
    .filter(Objects::nonNull)
    .collect(Collectors.groupingBy(DataType::of));✅ 策略三:数字类型的精细化过滤(范围筛选)
需求:从所有数字中筛选出值在 100 ~ 500 之间的项。
实现:
List<Number> filteredNumbers = mixed.stream()
    .filter(Objects::nonNull)
    .filter(item -> item instanceof Number)
    .map(item -> (Number) item)
    .filter(num -> {
        double value = num.doubleValue(); // 统一转为 double 比较
        return value >= 100 && value <= 500;
    })
    .collect(Collectors.toList());✅ 注意事项:
- 使用 doubleValue()可避免Long超出Integer范围的问题。
- 对精度要求高时,可用 BigDecimal.valueOf(num.doubleValue())。
✅ 策略四:字符串的模式匹配过滤(正则 + 条件)
需求:从字符串中筛选出符合邮箱格式的项。
实现:
Pattern emailPattern = Pattern.compile("\\w+@\\w+\\.\\w+");
List<String> emails = mixed.stream()
    .filter(Objects::nonNull)
    .filter(item -> item instanceof String)
    .map(String::valueOf)
    .filter(s -> !s.trim().isEmpty())
    .filter(emailPattern.asPredicate())
    .collect(Collectors.toList());✅ 扩展:识别并转换数字字符串
// 筛选出能转为整数的字符串
List<Integer> intStrings = mixed.stream()
    .filter(Objects::nonNull)
    .filter(item -> item instanceof String)
    .map(String::valueOf)
    .filter(s -> s.matches("\\d+"))
    .map(Integer::parseInt)
    .collect(Collectors.toList());✅ 策略五:构建类型安全的“过滤管道”(Pipeline)
为了提升可维护性,我们可以构建一个类型过滤管道:
public class ObjectFilterPipeline<T> {
    private final List<T> data;
    public ObjectFilterPipeline(List<T> data) {
        this.data = new ArrayList<>(data);
    }
    public ObjectFilterPipeline<T> ofType(Class<T> type) {
        return new ObjectFilterPipeline<>(
            data.stream()
                .filter(item -> type.isInstance(item))
                .collect(Collectors.toList())
        );
    }
    public ObjectFilterPipeline<String> strings() {
        return (ObjectFilterPipeline<String>) ofType(String.class);
    }
    public ObjectFilterPipeline<Number> numbers() {
        return (ObjectFilterPipeline<Number>) ofType(Number.class);
    }
    public ObjectFilterPipeline<T> where(Predicate<T> condition) {
        return new ObjectFilterPipeline<>(
            data.stream()
                .filter(condition)
                .collect(Collectors.toList())
        );
    }
    public List<T> result() {
        return new ArrayList<>(data);
    }
}✅ 使用方式(流式调用):
List<Object> result = new ObjectFilterPipeline<>(mixedData)
    .numbers()
    .where(num -> num.doubleValue() > 100)
    .result(); // 返回 List<Number>
List<String> emails = new ObjectFilterPipeline<>(mixedData)
    .strings()
    .where(s -> s.contains("@"))
    .result();✅ 优势:链式调用,语义清晰,类型安全(在转换后)。
✅ 5种策略对比速查表
| 策略 | 适用场景 | 优点 | 缺点 | 
| instanceof | 基础类型过滤 | 简单直接,性能好 | 重复代码多 | 
| 分组分类 | 数据清洗、统计 | 一次性分类,便于分析 | 内存占用略高 | 
| 数字范围 | 金额、评分、数量筛选 | 精准控制数值条件 | 需统一数值类型 | 
| 正则匹配 | 字符串模式识别 | 灵活,支持复杂规则 | 正则性能开销 | 
| 过滤管道 | 复杂业务逻辑链 | 链式调用,可扩展 | 需要额外封装 | 










