MapStruct: map from multiple variables to a collection

Viewed 487

I got the following situation:

Source class:

public class OutcodeStats {
     double avgPrice;
     double avgPricePsf;
     double avgRent;
     double avgYield;
     double growth1y;
     double growth3y;
     double growth5y;
     String outcode;
     int salesPerMonth;
     int turnover;
     long effectiveDate;
}

target class:

  public class GrowthStats {
    public String status;
    public String postcode;
    public String postcode_type;
    public String url;
    public List<List<Object>> data;
    public String process_time;
}

How do I instruct mapStruct to:

  • map growth1y, growth3y and growth5y in data?
  • ignore all the remaining fields

In other words, how to make this "pseudo" mapping working?

   @Mapper
public interface OutcodeStatsMapper {

    OutcodeStatsMapper INSTANCE = Mappers.getMapper(OutcodeStatsMapper.class);

    @Mapping(source="outcode", target = "postcode")
    @Mapping(source = "growth1y", target = "data")
    @Mapping(source = "growth3y", target = "data")
    @Mapping(source = "growth5y", target = "data")
    GrowthStats outcodeStatsToGrowthStats(OutCodeStats stats);
}

Here an example of the source class:

     "outcode":"BR1",
     "avg_price":436061.3,
     "avg_price_psf":0,
     "avg_rent":295.2,
     "avg_yield":"3.5%",
     "growth_1y":"5.6%",
     "growth_3y":"6.3%",
     "growth_5y":"17.9%",
     "sales_per_month":28,
     "turnover":"4%"

and here what I would love to see in the mapped object:

    "status":"success",
   "postcode":"BR1",
   "postcode_type":"outcode",
   "url":"https:\/\/propertydata.co.uk\/draw?input=BR1",
   "data":[
      [
         null,
         null,
         "3.5"
      ],
      [
         null,
         null,
         "5.6"
      ],
      [
         null,
         null,
         "6.3"
      ]
   ],
   "process_time":"0.26"
1 Answers

Here the way I made it working:

    @Mapper
public interface OutcodeStatsMapper {

    OutcodeStatsMapper INSTANCE = Mappers.getMapper(OutcodeStatsMapper.class);

    @Mapping(source = "outcode", target = "postcode")
    GrowthStats outcodeStatsToGrowthStats(OutCodeStats stats);

    @AfterMapping
    default void fillData(OutCodeStats outCodeStats, @MappingTarget GrowthStats growthStats) {
        growthStats.status = "success";
        growthStats.postcode_type= "outcode";
        growthStats.data = new ArrayList<>();
        Stream.of(outCodeStats.growth1y, outCodeStats.growth3y, outCodeStats.growth5y)
                .forEach(yearStats -> growthStats.data.add(List.of("null", "null", yearStats)));
    }
}
Related