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

无需Guava:如何用MapStruct实现List转List时填充元素索引?

需求场景

我有Source和Target两个类,其中Target类多了一个index字段。现在需要把Source对象列表转换成Target对象列表,要求Target的index字段对应原列表中Source对象的位置索引。

目前我用Guava实现了一个可行方案:

List<Target> mapList(List<Source> sources) {
    return Streams.mapWithIndex(sources.stream(), (source, index) -> mapElement(source, (int) index)).toList();
}

abstract Target mapElement(Source source, int index);

现在想移除Guava依赖,改用MapStruct实现,但查官方文档没找到相关说明,求实现技巧。


实现方案

MapStruct本身没有内置的列表索引传递机制,但可以通过自定义默认方法结合手动遍历/原生Stream来实现需求,以下是两种可行技巧:

方法1:自定义列表映射方法,手动遍历传索引

先定义单个元素的映射接口(包含索引参数),再写一个默认的列表转换方法,手动遍历原列表并传递每个元素的索引:

@Mapper
public interface SourceTargetMapper {
    // 单个元素映射,接收index参数,MapStruct会自动实现字段映射逻辑
    Target sourceToTarget(Source source, int index);

    // 默认实现列表转换逻辑
    default List<Target> sourcesToTargets(List<Source> sources) {
        List<Target> targets = new ArrayList<>(sources.size());
        for (int i = 0; i < sources.size(); i++) {
            targets.add(sourceToTarget(sources.get(i), i));
        }
        return targets;
    }
}

如果需要更灵活的对象初始化,也可以用@MappingTarget方式:

@Mapper
public interface SourceTargetMapper {
    void sourceToTarget(Source source, @MappingTarget Target target, int index);

    default List<Target> sourcesToTargets(List<Source> sources) {
        List<Target> targets = new ArrayList<>(sources.size());
        for (int i = 0; i < sources.size(); i++) {
            Target target = new Target();
            sourceToTarget(sources.get(i), target, i);
            targets.add(target);
        }
        return targets;
    }
}

方法2:结合Java原生Stream实现

和你原来的Guava思路类似,但改用Java原生IntStream来遍历索引,完全摆脱Guava依赖:

@Mapper
public interface SourceTargetMapper {
    Target sourceToTarget(Source source, int index);

    default List<Target> sourcesToTargets(List<Source> sources) {
        return IntStream.range(0, sources.size())
                .mapToObj(i -> sourceToTarget(sources.get(i), i))
                .collect(Collectors.toList());
    }
}

注意事项
  • 确保Target类的index字段有公开的setter方法,或是公共成员变量,MapStruct才能完成赋值。
  • 如果Source和Target的字段名不一致,需要添加@Mapping(source = "原字段名", target = "目标字段名")注解指定映射关系。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 07:30:58