MapStruct 从 arrayList 中检索

0 java mapstruct

我正在尝试使用 MapStruct 来映射两个对象。我一直在寻找一段时间,但我什么也没找到,尽管我是编程新手,所以我确信它比我制作它更容易。

这是一些剥离的代码(请注意,实际代码更复杂,来自 arraylist 的子对象与此处的目标对象子变量的类型不同):

源对象

public class SourceObject {
    public ArrayList<ListObject> list = new ArrayList<ListObject>();

    public SourceObject() {
        list.add(new ListObject());
    }
}
Run Code Online (Sandbox Code Playgroud)

列表对象

public class ListObject {
    public DetailsObject details = new DetailsObject();

    public ListObject() {
        details.forename="SourceForename";
        details.surname="SourceSurname";
    }
}
Run Code Online (Sandbox Code Playgroud)

目标对象

public class DestinationObject {
    public DetailsObject details = new DetailsObject();

    public DestinationObject() {
        details.forename="DestinationForename";
        details.surname="DestinationSurname";
    }
}
Run Code Online (Sandbox Code Playgroud)

详细信息对象

public class DetailsObject {
    public String forename;
    public String surname;
}
Run Code Online (Sandbox Code Playgroud)

映射器

@Mappings({
    @Mapping(target="details.forename", source="list.get(0).details.forename"),
    @Mapping(target="details.surname", source="list.get(0).details.surname"),
})
DestinationObject toDestination(SourceObject source);
Run Code Online (Sandbox Code Playgroud)

如果我将 DetailsObject 直接放在 SourceObject 中,这会正常工作,但是当我尝试从列表中取出它时会出现问题。我得到的错误是:

[错误] 无法在项目模板上执行目标 org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile (default-compile): Compilation failure: Compilation failure:

[错误] .../src/main/java/Mapper/SourceToDestinationMap.java:[12,13] 源参数中不存在名为“list.get(0).details.surname”的属性。您指的是 “list.empty” 吗?

[错误] .../src/main/java/Mapper/SourceToDestinationMap.java:[11,9] 源参数中不存在名为“list.get(0).details.forename”的属性。您指的是 “list.empty” 吗?

编辑:映射器的当前状态:

@Mapper
public interface SourceToDestinationMap {

    @Mapping(target = "details", source = "list")
    DestinationObject toDestination(SourceObject source);

    default DetailsObject map(List<ListObject> source) {
        return map(source.get(0));
    }

    DetailsObject map(ListObject source);
}
Run Code Online (Sandbox Code Playgroud)

Fil*_*lip 5

您尝试进行的映射是不可能的,因为您正在混合 bean 属性和 bean 函数。

你不能使用@Mapping(source = "list.get(0).XXX"). 尚不支持使用索引访问列表的元素,请参阅#1321

解决您的问题的一种方法是以与mapstruct-iterable-to-non-iterable示例中使用的方式相同的方式使用限定符。

或者您可以提供自己的方法来执行映射。

@Mapper
public interface MyMapper {

    @Mapping(target = "details", source = "list")
    DestinationObject toDestination(SourceObject source);

    default DetailsObject map(List<ListObject> source) {
        return source != null && !source.isEmpty() ? map(source.get(0)) : null;
    }

    DetailsObject map(ListObject source);
}
Run Code Online (Sandbox Code Playgroud)

然后 MapStruct 将生成正确的代码。

另一种选择是使用@Mapping(expression="java()".

您的映射器将如下所示:

@Mapper
public interface MyMapper {

    @Mapping(target = "details.forename", expression = "java(source.list.get(0).details.forename)")
    @Mapping(target = "details.surname", expression = "java(source.list.get(0).details.surname)")
    DestinationObject toDestination(SourceObject source);
}
Run Code Online (Sandbox Code Playgroud)

注意为expression。MapStruct 将按原样使用表达式中的文本,并且不会执行任何验证检查。因此它可能有点脆弱,因为不会null有空支票。