将对象/地图与mapstruct合并

问题描述 投票:0回答:1

我有两个相同类型的对象。所有字段都是

Map<String, SomeType>
,因此对象看起来像:

class Obj {
  Map<String, TypeA> propA;
  Map<String, TypeB> propB;
  ...

  Obj setPropA(Map<String, TypeA> newMap) { ... }
  Obj setPropB(Map<String, TypeB> newMap) { ... }
  ...
 
  Obj putPropA(String key, TypeA a) { ... }
  Obj putPropB(String key, TypeB b) { ... }
  ...
}

我需要通过合并/连接所有映射条目来合并其中两个对象(字符串键永远不会冲突)。目前,这是手工完成的。但是,这看起来很笨拙,并且在生成类时,一旦添加属性,合并就不完整。

Obj merge(Obj ob1, Obj ob2) {
  return new Obj()
    .setPropA(mergeMaps(ob1.getPropA(), ob2.getPropA()))
    .setPropB(mergeMaps(ob1.getPropB(), ob2.getPropB()))
    ...;
}

<T> Map<String, T> mergeMaps(Map<String, T> aMap, Map<String, T> bMap) {
  aMap.putAll(bMap);
  return aMap;
}

可以使用mapstruct自动合并所有字段映射吗?

java mapstruct
1个回答
0
投票
@Mapper
public interface ObjMapper {

    ObjMapper INSTANCE = Mappers.getMapper(ObjMapper.class);
    
    Obj merge(Obj source, @MappingTarget Obj target);
    
    default <T> void mergeMaps(Map<String, T> source, @MappingTarget Map<String, T> target) {
        if ( source == null ) {
            return;
        }
        if ( target == null ) {
            target = new HashMap<>();
        }
        target.putAll(source);
    }
    
}

生成的代码是:

public class ObjMapperImpl implements ObjMapper {

    @Override
    public Obj merge(Obj source, Obj target) {
        if ( source == null ) {
            return target;
        }

        if ( source.getPropA() != null ) {
            if ( target.getPropA() == null ) {
                target.setPropA( new LinkedHashMap<String, ChildA>() );
            }
            mergeMaps( source.getPropA(), target.getPropA() );
        }
        else {
            target.setPropA( null );
        }
        if ( source.getPropB() != null ) {
            if ( target.getPropB() == null ) {
                target.setPropB( new LinkedHashMap<String, ChildB>() );
            }
            mergeMaps( source.getPropB(), target.getPropB() );
        }
        else {
            target.setPropB( null );
        }

        return target;
    }

}

唯一的区别是它对目标进行了更新。 如果需要有一个新的对象,则需要执行两次merge方法:

Obj newObj = new Obj();
newObj = ObjMapper.INSTANCE.merge(ob1, newObj); // add from ob1
newObj = ObjMapper.INSTANCE.merge(ob2, newObj); // add from ob2
© www.soinside.com 2019 - 2024. All rights reserved.