如何用Mapstruct将扁平化父子列表映射为嵌套父子结构?
使用Mapstruct实现扁平化列表到嵌套父子结构的映射
核心思路
Mapstruct擅长单对象的属性映射,但父子归组逻辑需要结合Java Stream的分组能力。我们可以先定义基础的单对象映射规则,再通过自定义方法完成分组和子列表的归集工作。
步骤1:定义Mapstruct映射接口
创建Mapper接口,分别实现Flattened到Parent、Flattened到Child的单对象映射,同时忽略Parent的children字段(后续手动处理):
import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Mapper(componentModel = "spring") // Spring环境用此配置,非Spring环境用default public interface FlattenedMapper { FlattenedMapper INSTANCE = Mappers.getMapper(FlattenedMapper.class); // 映射Flattened的父属性到Parent,忽略children字段 @Mapping(target = "children", ignore = true) Parent toParent(Flattened flattened); // 映射Flattened的子属性到Child Child toChild(Flattened flattened); // 核心方法:处理列表分组与子对象归集 default List<Parent> map(List<Flattened> flattenedList) { // 按parentId对扁平化列表分组 Map<Integer, List<Flattened>> groupedByParentId = flattenedList.stream() .collect(Collectors.groupingBy(Flattened::getParentId)); // 遍历分组,生成嵌套结构的Parent列表 return groupedByParentId.entrySet().stream() .map(entry -> { List<Flattened> group = entry.getValue(); // 取分组内第一个对象映射父属性(假设同parentId的父属性完全一致) Parent parent = toParent(group.get(0)); // 将分组内所有对象映射为Child并归集到Parent的children List<Child> children = group.stream() .map(this::toChild) .collect(Collectors.toList()); parent.setChildren(children); return parent; }) .collect(Collectors.toList()); } }
关键细节说明
- 假设同一
parentId对应的所有Flattened对象的父属性(someParentProperty1等)完全一致,因此取分组内第一个对象映射父属性即可。如果存在属性不一致的场景,需要额外添加属性合并的逻辑。 - 若使用Spring框架,
@Mapper的componentModel设为spring后,可直接通过依赖注入使用Mapper;非Spring环境用default,通过INSTANCE静态调用即可。 - Mapstruct会自动生成
toParent和toChild的属性映射实现,无需手动编写重复的赋值代码。
使用示例
// 测试代码示例 List<Flattened> flattenedList = Arrays.asList( new Flattened(1, 101, "父属性A", "子属性101"), new Flattened(1, 102, "父属性A", "子属性102"), new Flattened(2, 201, "父属性B", "子属性201") ); List<Parent> parents = FlattenedMapper.INSTANCE.map(flattenedList); // 结果:2个Parent对象,第一个Parent包含2个Child,第二个包含1个Child
内容的提问来源于stack exchange,提问作者gzak
相关产品推荐
相关产品推荐

