如何无需手动设置字段,利用多对象字段创建新List
问题描述
现有两个无法修改的Java类FhExtraImportResults和FhExtra,需要将List<FhExtraImportResults>转换为包含FhExtra的所有字段,以及FhExtraImportResults中除record外其他字段的新列表。目前通过手动逐个设置字段的方式实现,希望找到更高效的替代方案。
相关类定义
public class FhExtraImportResults { FhExtra record; String error; Long loanId; } @Data public class FhExtra { String LoanNumber; String FILoanNumber; }
期望输出结构示例
[{ "LoanNumber": "123", "FILoanNumber": "321", "error": "NA", "loanId": 456 }]
优化实现方案
以下几种方案可避免手动逐个赋值的繁琐,适配字段较多的场景:
1. Spring BeanUtils(快速轻量)
利用Spring的BeanUtils工具类批量复制字段,无需手动编写赋值逻辑,适合快速实现:
import org.springframework.beans.BeanUtils; import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; public class Converter { public static List<HashMap<String, Object>> convert(List<FhExtraImportResults> inputList) { return inputList.stream().map(item -> { HashMap<String, Object> resultMap = new HashMap<>(); // 复制FhExtraImportResults中除record外的字段 BeanUtils.copyProperties(item, resultMap, "record"); // 复制FhExtra的所有字段 if (item.getRecord() != null) { BeanUtils.copyProperties(item.getRecord(), resultMap); } // 给error字段设置默认值NA if (resultMap.get("error") == null) { resultMap.put("error", "NA"); } return resultMap; }).collect(Collectors.toList()); } }
2. MapStruct(类型安全,高性能)
MapStruct是编译期生成映射代码的工具,性能优于反射类工具,且能保证类型安全,适合复杂映射场景:
首先添加Maven依赖:
<dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.5.5.Final</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.5.5.Final</version> <scope>provided</scope> </dependency>
定义映射接口与目标DTO:
import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Named; import java.util.List; @Mapper(componentModel = "spring") public interface FhExtraResultMapper { @Mapping(source = "record.LoanNumber", target = "LoanNumber") @Mapping(source = "record.FILoanNumber", target = "FILoanNumber") @Mapping(source = "error", target = "error", qualifiedByName = "defaultNA") TargetDto mapToDto(FhExtraImportResults source); List<TargetDto> mapToList(List<FhExtraImportResults> sourceList); @Named("defaultNA") default String defaultNA(String error) { return error == null ? "NA" : error; } } // 自定义目标DTO public class TargetDto { private String LoanNumber; private String FILoanNumber; private String error; private Long loanId; // 生成getter、setter(或使用@Data注解) }
使用时直接注入Mapper调用:
@Autowired private FhExtraResultMapper mapper; public List<TargetDto> convert(List<FhExtraImportResults> input) { return mapper.mapToList(input); }
3. Jackson序列化合并(适配JSON输出场景)
如果最终需要输出JSON格式,可直接用Jackson将对象转为Map后合并字段:
import com.fasterxml.jackson.databind.ObjectMapper; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class JsonConverter { private static final ObjectMapper objectMapper = new ObjectMapper(); public static List<Map<String, Object>> convert(List<FhExtraImportResults> inputList) throws Exception { return inputList.stream().map(item -> { try { Map<String, Object> resultMap = objectMapper.convertValue(item, Map.class); resultMap.remove("record"); // 合并FhExtra的字段 if (item.getRecord() != null) { Map<String, Object> recordMap = objectMapper.convertValue(item.getRecord(), Map.class); resultMap.putAll(recordMap); } // 设置error默认值 if (resultMap.get("error") == null) { resultMap.put("error", "NA"); } return resultMap; } catch (Exception e) { throw new RuntimeException("转换失败", e); } }).collect(Collectors.toList()); } }
4. 手动反射(无第三方依赖)
如果不想引入外部库,可通过Java反射遍历字段实现复制:
import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class ReflectConverter { public static List<Map<String, Object>> convert(List<FhExtraImportResults> inputList) throws IllegalAccessException { List<Map<String, Object>> resultList = new ArrayList<>(); for (FhExtraImportResults item : inputList) { Map<String, Object> resultMap = new HashMap<>(); // 处理FhExtraImportResults的字段 Field[] resultFields = FhExtraImportResults.class.getDeclaredFields(); for (Field field : resultFields) { field.setAccessible(true); if (!"record".equals(field.getName())) { Object value = field.get(item); if ("error".equals(field.getName()) && value == null) { resultMap.put(field.getName(), "NA"); } else { resultMap.put(field.getName(), value); } } } // 处理FhExtra的字段 if (item.getRecord() != null) { Field[] extraFields = FhExtra.class.getDeclaredFields(); for (Field field : extraFields) { field.setAccessible(true); resultMap.put(field.getName(), field.get(item.getRecord())); } } resultList.add(resultMap); } return resultList; } }
内容的提问来源于stack exchange,提问作者VKP
相关产品推荐
相关产品推荐

