如何在java中合并两个大的POJO?

时间:2016-01-04 14:55:56

标签: java

如何在Java中合并2个大的相同POJO(~40个字段)?

实施例

Satellite A: [name = ISS, period = 0.9, inclination = 0.8, launch_date=2016-01-04, launch_vehicle=null, has_propulsion=null]

Satellite B: [name = International Space station, period= 0.91, inclination =0.802, launch_vehicle=BOAT, has_propulsion=false]

Satellite C: [name = ISS, period = 0.9, inclination = 0.8, launch_date=2016-01-04, launch_vehicle=BOAT, has_propulsion=false]

5 个答案:

答案 0 :(得分:3)

好吧,使用反射会是这样的:

public static Satellite merge(Satellite s1, Satellite s2) throws Exception {

    Satellite merged = new Satellite();

    for (Field field : Satellite.class.getDeclaredFields()) {
        field.set(merged, field.get(s1) != null? field.get(s1) : field.get(s2));
    }

    return merged;
}

但我认为这绝对是一种糟糕的(危险的和缓慢的)方法。实际上,我会选择m0skit0解决方案,但首先请打破你的课程。你不应该有一个有40个字段的课......

答案 1 :(得分:2)

我会选择构造函数,例如:

public MergedSatellite(final Satellite one, final Satellite other) {
    setOffName((one.getOffName() == null) ? other.getOffName() : one.getOffName());
    // And so on for all fields
}

编辑:请注意,当两个实例上都存在该字段时,这会使one超过other。您可能希望在合并过程中考虑更多逻辑。

答案 2 :(得分:1)

答案 3 :(得分:0)

确实取决于您要解决的问题。合并的约束条件是什么?

一种解决方案可能是在C类中包装两个类,并为每个get方法使用三元运算符,代码可能至少是可读的而不是冗长的。 return isNotBlank(a.getName())?a.getName():b.getName();

还有其他选项,例如使用通常不推荐的java反射。

答案 4 :(得分:0)

使用 Jackson

Satellite finalSatellite = new Satellite();
ObjectReader objectReader = objectMapper.readerForUpdating(finalSatellite);
// inversed order, because in the question, satelliteA's values have to win
objectReader.readValue(objectMapper.<JsonNode>valueToTree(satelliteB));
objectReader.readValue(objectMapper.<JsonNode>valueToTree(satelliteA));
// finalSatellite contains the merged result

重要说明:

  1. 确保在 POJO 上使用 @JsonInclude(JsonInclude.Include.NON_NULL) 或在 objectMapper 级别进行配置。这是必需的,以避免用空值覆盖非空值
  2. 确保在包含 deep merging 的嵌套 POJO 的字段上使用 @JsonMerge