我在其他地方看到过这个问题,但并不是在完全相同的背景下提出的,而且没有一个适用于我们用例的答案。
假设我在源对象中有一个list字段:
List<MySourceElement> mySourceList;以及相应的目标字段:
List<MyTargetElement> myTargetList;我只想在执行一个标准的mySourceList映射器将MySourceElement映射到myTargetList之前,能够通过MySourceElement的某些属性过滤源mySourceList中的元素。
假设MySourceElement有一个布尔属性isValid,我们的过滤器谓词是简单的(isValid == true),而MyTargetElement没有对应的布尔值。
我尝试过许多方法,包括@DecoratedWith和qualifiedBy:
qualifiedBy方法类似于:
@FilterForValid
public List<MySourceElement> filterForValid(List<MySourceElement> mySourceElement) {
... implementation ...
}我的地图宣言是这样的:
@Mapping(source = "mySourceList", target = "myTargetList", qualifiedBy = FilterForValid.class)
Target sourceToTarget(Source source);我想要一个qualifiedBy的实现,比如:
target.withMyTargetList(
mySourceListToMyTargetList(filterUtil.filterForValid(source.getMySourceList))); 与其让qualifiedBy工作,我会很高兴找到如何使用@BeforeMapping来实现这一点,但我不清楚如何从文档中实现这一点,特别是因为对于所有意图和目的,源对象应该被认为是不可变的。
任何关于以这种方式调用映射器的最简单的、首选的方法来进行集合过滤的指导都将不胜感激。
发布于 2019-03-29 19:56:08
这里有一个被请求的特性地图/地图#1610,它允许对类似的东西使用开箱即用的支持。尽管如此,解决这一问题的一种方法是使用@Context注释。然后,您的映射器可以看起来如下:
@Mapper
public interface MyMapper {
Target map(Source source, @Context Predicate<MySourceElement> predicate);
default List<MySourceElement> mapAndFilter(List<MySourceElement> list, @Context Predicate<MySourceElement> predicate) {
List<MySourceElement> newList = new ArrayList<>();
for(MySourceElement el : list) {
if (predicate.test(el)) {
newList.add(map(el));
}
}
return newList;
}
MySourceElement map(MySourceElement el);
}https://stackoverflow.com/questions/55424178
复制相似问题