如何用MapStruct将主对象中的对象列表映射为另一对象列表
MapStruct 映射对象列表到字符串列表的解决方案
你直接用@Mapping(target = "number", source = "pool")失败的原因是:MapStruct无法自动将Pool对象转换为String,必须明确指定转换规则,要么定义单个元素的转换逻辑,要么直接处理整个列表的映射。
先明确实体类结构(参考)
// ObjectA.java public class ObjectA { private Long id; private List<Pool> pool; // 省略getter、setter } // Pool.java public class Pool { private Student student; // 省略getter、setter } // Student.java public class Student { private Long id; private String number; // 省略getter、setter } // ObjectB.java public class ObjectB { private Long id; private List<String> number; // 省略getter、setter }
方法一:自定义单个元素转换方法(推荐)
定义一个default方法告诉MapStruct如何将单个Pool转为学生编号,MapStruct会自动把这个规则应用到列表上:
import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; @Mapper public interface ObjectMapper { ObjectMapper INSTANCE = Mappers.getMapper(ObjectMapper.class); @Mapping(target = "number", source = "pool") ObjectB mapObjectAtoObjectB(ObjectA objectA); // 处理单个Pool到学生编号的转换,自动兼容空值 default String mapPoolToStudentNumber(Pool pool) { return pool != null && pool.getStudent() != null ? pool.getStudent().getNumber() : null; } }
方法二:自定义列表级转换方法
如果需要过滤空值这类复杂逻辑,可以直接定义列表转换方法,通过qualifiedByName指定使用:
import java.util.List; import java.util.stream.Collectors; import org.mapstruct.Named; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; @Mapper public interface ObjectMapper { ObjectMapper INSTANCE = Mappers.getMapper(ObjectMapper.class); @Mapping(target = "number", source = "pool", qualifiedByName = "extractStudentNumbers") ObjectB mapObjectAtoObjectB(ObjectA objectA); @Named("extractStudentNumbers") default List<String> extractStudentNumbers(List<Pool> pools) { if (pools == null) { return null; } return pools.stream() .filter(pool -> pool != null && pool.getStudent() != null) .map(pool -> pool.getStudent().getNumber()) .collect(Collectors.toList()); } }
方法三:使用表达式直接处理
适合简单场景,通过expression字段直接编写Java逻辑:
import java.util.stream.Collectors; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; @Mapper(imports = {Collectors.class}) public interface ObjectMapper { ObjectMapper INSTANCE = Mappers.getMapper(ObjectMapper.class); @Mapping(target = "number", expression = "java(objectA.getPool().stream().filter(p -> p != null && p.getStudent() != null).map(p -> p.getStudent().getNumber()).collect(Collectors.toList()))") ObjectB mapObjectAtoObjectB(ObjectA objectA); }
调用示例
业务代码中直接使用Mapper实例即可完成映射:
ObjectA objectA = new ObjectA(); // 初始化objectA的id和pool列表数据 ObjectB objectB = ObjectMapper.INSTANCE.mapObjectAtoObjectB(objectA);
内容的提问来源于stack exchange,提问作者SRG
相关产品推荐
相关产品推荐

