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

如何基于类映射ArrayList<Object>为ArrayList<String>实现字段非空校验

实现优化方案

一、类型映射逻辑优化

原来的mapToString用串行instanceof判断扩展性差,且每次调用时重复创建DateTimeFormatter实例会造成不必要的性能消耗,优化如下:

// 提前创建静态不可变的日期格式化器,线程安全可复用
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy");
// 类型映射表,新增支持的组件类型只需在这里添加条目,无需修改核心转换逻辑
private static final Map<Class<?>, Function<Object, String>> TYPE_CONVERTER = Map.of(
        JPasswordField.class, o -> new String(((JPasswordField) o).getPassword()),
        JTextField.class, o -> ((JTextField) o).getText(),
        DatePicker.class, o -> {
            LocalDate date = ((DatePicker) o).getDate();
            return date != null ? date.format(DATE_FORMATTER) : "";
        },
        JComboBox.class, o -> {
            Object selected = ((JComboBox<?>) o).getSelectedItem();
            return selected != null ? selected.toString() : "";
        }
);

private static String mapToString(Object o) throws IllegalArgumentException {
    Function<Object, String> converter = TYPE_CONVERTER.get(o.getClass());
    if (converter == null) {
        // 如果需要支持子类匹配,可替换为遍历key判断isAssignableFrom的逻辑
        throw new IllegalArgumentException("不支持的组件类型:" + o.getClass().getName());
    }
    return converter.apply(o);
}

如果需要支持子类匹配(比如自定义继承了JTextField的组件),可以把映射表的查询逻辑替换为遍历匹配:

private static String mapToString(Object o) throws IllegalArgumentException {
    for (Map.Entry<Class<?>, Function<Object, String>> entry : TYPE_CONVERTER.entrySet()) {
        if (entry.getKey().isInstance(o)) {
            return entry.getValue().apply(o);
        }
    }
    throw new IllegalArgumentException("不支持的组件类型:" + o.getClass().getName());
}

二、ArrayList转换逻辑优化

原来的stream.map().forEach(b::add)写法需要依赖外部集合,不符合Stream的函数式编程规范,直接用collect生成集合即可:

List<String> b = a.stream()
        .map(Validatore::mapToString)
        .collect(Collectors.toCollection(ArrayList::new));

三、非空校验逻辑优化

原校验逻辑存在两处问题:

  1. peek(System.out.println("Empty"))写法错误,peek需要传入消费函数,该写法会在Stream启动前就执行打印,不符合预期
  2. 校验逻辑过于冗余,可直接用Stream内置的匹配方法简化
    优化后的校验代码:
// 返回true代表所有组件值均非空,false代表存在空值
return a.stream()
        .map(Validatore::mapToString)
        .peek(s -> {
            if (s.isEmpty()) {
                System.out.println("Empty");
            }
        })
        .noneMatch(String::isEmpty);

如果不需要对空值做打印逻辑,可直接去掉peek段,代码更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 15:27:02