【问题标题】:How to flatten nested json to map with entity using Java 8 Stream?如何使用 Java 8 Stream 展平嵌套的 json 以映射到实体?
【发布时间】:2021-11-28 13:10:09
【问题描述】:

对于 RechargeResponse 模型,我有一个如下所示的结构:

public class RechargeResponse {
    private String code;
    private String status;
    private Set<OperatorWiseCircles> payload; 
   // setter and getters
}

这是 OperatorWiseCircles 模型

public class OperatorWiseCircles {
    private String operatorName;
    private String operatorId;
    private List<CircleWisePlan> circleWisePlanLists;
//setter and getters
}

CircleWisePlan 模型类

public class CircleWisePlan {
    private String circleName;
    private String circleId;
}

下面是我们需要扁平化的示例 json。

{
  "code": 200,
  "status": "SUCCESS",
  "payload": [
    {
      "operatorName": "VODAFONE",
      "operatorId": "VF",
      "circleWisePlanLists": [
        {
          "circleName": "C1",
          "circleId": "1"
        },
        {
          "circleName": "C2",
          "circleId": "2"
        }
      ]
    }
  ]
}

我希望这是扁平化并将其映射到实体对象,以便我可以将所有这些迭代添加到 Hashset 并将它们全部保存到 DB,我想使用 java8 流来完成。我怎样才能有效地做到这一点。我没有得到正确的示例来解析嵌套的 json 值并使用 map/flatmap 为其创建实体。 结果应该是这样的

例如:["VODAFONE","VF","C1","1"]---> 条目 1 [“沃达丰”,“VF”,“C2”,“2”] ---> ENTRY2

@Entity
public class RechargePlanEntity extends Audit<String>{
    @Id
    @Column(name="id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name="operator_name")
    private String operatorName;

    @Column(name="operator_id")
    private String operatorId;

    @Column(name="circle_name")
    private String circleName;

    @Column(name="circle_id")
    private String circleId;       

}

【问题讨论】:

  • 你也可以添加你的实体对象吗?
  • 也添加了实体

标签: java spring spring-boot java-8 spring-data-jpa


【解决方案1】:

事实是,我敢肯定有什么简单的方法可以做到这一点,但你可以按照这样的方式进行操作,

在此示例中,我创建了实用程序类以将 OperatorWiseCircles 类映射到 List&lt;RechargePlanEntity&gt;

public class Main {
    public static void main(String[] args) throws IOException {

        String s = "{\"code\":200,\"status\":\"SUCCESS\",\"payload\":[{\"operatorName\":\"VODAFONE\",\"operatorId\":\"VF\",\"circleWisePlanLists\":[{\"circleName\":\"C1\",\"circleId\":\"1\"},{\"circleName\":\"C2\",\"circleId\":\"2\"}]}]}";

        ObjectMapper om = new ObjectMapper();
        RechargeResponse response = om.readValue(s, RechargeResponse.class);

        List<RechargePlanEntity> collection = response.getPayload()
                .stream()
                .map(MapUtil::toEntity)
                .flatMap(Collection::stream)
                .collect(Collectors.toList());

        System.out.println(collection);
    }
}

@Getter
@Setter
@ToString
class RechargePlanEntity {
    private Long id;
    private String operatorName;
    private String operatorId;
    private String circleName;
    private String circleId;
}

@Getter
@Setter
class RechargeResponse {
    private String code;
    private String status;
    private Set<OperatorWiseCircles> payload;
}

@Getter
@Setter
class OperatorWiseCircles {
    private String operatorName;
    private String operatorId;
    private List<CircleWisePlan> circleWisePlanLists;
}

@Getter
@Setter
class CircleWisePlan {
    private String circleName;
    private String circleId;
}

final class MapUtil {

    public static List<RechargePlanEntity> toEntity(OperatorWiseCircles in) {
        return in.getCircleWisePlanLists()
                .stream()
                .map(MapUtil::map)
                .peek(out -> map(in, out))
                .collect(Collectors.toList());
    }

    private static RechargePlanEntity map(CircleWisePlan in) {
        RechargePlanEntity out = new RechargePlanEntity();
        out.setCircleId(in.getCircleId());
        out.setCircleName(in.getCircleName());
        return out;
    }

    private static void map(OperatorWiseCircles in, RechargePlanEntity out) {
        out.setOperatorId(in.getOperatorId());
        out.setOperatorName(in.getOperatorName());
    }
}

【讨论】:

    【解决方案2】:

    如果实体具有全参数构造函数,则可以从 RechargeResponse 模型创建没有 ID 的实体:

    RechargeResponse modelFromJson = ... //
    
    List<RechargePlanEntity> entities = modelFromJson.getPayload()
            .stream() // Stream<OperatorWiseCircles>
            .flatMap(ows -> ows.getCircleWisePlanLists()
                               .stream() // Stream<CircleWisePlan>
                               .map(cwp -> new RechargePlanEntity(
                                   null, // instead of id
                                   ows.getOperatorName(),
                                   ows.getOperatorId(),
                                   cwp.getCircleName(),
                                   cwp.getCircleId()
                               )) // Stream<RechargePlanEntity>
            ) // Stream<RechargePlanEntity>
            .collect(Collectors.toList());
    

    或者,如果在实体类中实现了构建器(例如,使用 Lombok 的 @Builder 注释),则此转换可能如下所示:

    List<RechargePlanEntity> entities = modelFromJson.getPayload()
            .stream() // Stream<OperatorWiseCircles>
            .flatMap(ows -> ows.getCircleWisePlanLists()
                               .stream() // Stream<CircleWisePlan>
                               .map(cwp -> RechargePlanEntity.builder()
                                   .operatorName(ows.getOperatorName())
                                   .operatorId(ows.getOperatorId())
                                   .circleName(cwp.getCircleName())
                                   .circleId(cwp.getCircleId())
                                   .build()
                               ) // Stream<RechargePlanEntity>
            ) // Stream<RechargePlanEntity>
            .collect(Collectors.toList());
    

    【讨论】:

      猜你喜欢
      • 2016-09-24
      • 2017-08-22
      • 2019-05-16
      • 1970-01-01
      • 2016-02-12
      • 1970-01-01
      • 2018-07-10
      • 2020-01-20
      • 2019-01-19
      相关资源
      最近更新 更多