【问题标题】:how to parse complex object using Java 8 stream?如何使用 Java 8 流解析复杂对象?
【发布时间】:2021-09-09 16:58:41
【问题描述】:

我有如下 json 对象,我需要解析并返回逗号分隔值

{
 "globalCode" : "12"
  "fields" : [
     {
           "localCode" : "72879",
           "fieldValues" : [
                {
                      "value" : null,
                      "subFields" : [
                           {
                                 "localCode" : "980"
                                 "subFieldValues" : [
                                         {
                                          "value" :  "lon"
                                         }
                                  ]
                           },
                            {
                                 "localCode" : "98"
                                 "subFieldValues" : [
                                         {
                                          "value" :  "KPO"
                                         }
                                  ]
                           }
                              

                      ]
                }       
           ]
     }
  ]
}

我想使用 java 8 流实现以下目标。以下函数应返回字符串 "lon,KPO"

以下函数中的第 2 行,从字段数组中返回 一个字段对象 我不确定如何使用 java 8 Streams 添加其他部分。

public String getValue(){
    StringBuffer buffer = new StringBuffer();
    List<Field> fields  = //get fields for globalCode 72879 // line 2
    for(Field field : fields    ){
         List<FieldValue> fieldValues : field.getFieldValues();
         for(FieldValue fieldValue : fieldValues)
         {
           if(fieldValue.getValue() != null){
               buffer.append(fieldValue.getValue());
               buffer.append(",");
           }
           else{
               List<SubField> subFields = values.getSubFields();
               for(SubField subField: subFields ){
                  List<SubFieldValue> subFieldValues : subField.getSubFieldValues();
                 for(SubFieldValue subFieldValue : subFieldValues  ){
                        buffer.append(subFieldValue.getValue());
                        buffer.append(",");
                 }        
              }
            }
         }
    }
     return buffer.toString();
}

【问题讨论】:

  • 嗨!你的代码有效吗?有些语句甚至无法在 java 中编译,例如List&lt;SubField&gt; subFields = values.getSubFields();,您的代码中没有 values 对象。请提供一个工作代码示例。并且List&lt;FieldValue&gt; fieldValues : field.getFieldValues(); 行也没有编译,猜你需要用= 替换:
  • "我想使用 java 8 流实现以下目标" - 但是您还没有提供任何与 Stream 相关的代码。向我们展示您无法开始工作的 Stream 相关代码,并通过该代码描述您的问题。

标签: java java-8 stream


【解决方案1】:
fields.stream().flatMap(field -> field.getFieldValues().stream()).forEach(fieldValue -> {
            if (fieldValue.getValue() != null) {
                buffer.append(fieldValue.getValue());
                buffer.append(",");
            } else {
                List<SubField> subFields = fieldValue.getSubFields();
                for (SubField subField : subFields) {
                    List<SubFieldValue> subFieldValues = subField.getSubFieldValues();
                    for (SubFieldValue subFieldValue : subFieldValues) {
                        buffer.append(subFieldValue.getValue());
                        buffer.append(",");
                    }
                }
            }
        });

如果您还想替换 else 语句中的 for 循环:

fields.stream().flatMap(field -> field.getFieldValues().stream()).forEach(fieldValue -> {
            if (fieldValue.getValue() != null) {
                buffer.append(fieldValue.getValue());
                buffer.append(",");
            } else {
                List<SubField> subFields = fieldValue.getSubFields();
                subFields.stream().map(SubField::getSubFieldValues).forEach(subFieldValues -> subFieldValues.forEach(subFieldValue -> {
                    buffer.append(subFieldValue.getValue());
                    buffer.append(",");
                }));
            }
        });

【讨论】:

    【解决方案2】:

    你可以这样做:

    Stream.concat(
              list.stream().flatMap(field -> field.getFieldValues().stream()
                                        .map(FieldValue::getValue)), 
               list.stream()
                   .flatMap(field -> field.getFieldValues().stream())
                   .flatMap(fieldValue -> fieldValue.getSubFields().stream())
                   .flatMap(subField -> subField.getSubFieldValues().stream())
                   .map(SubFieldValue::getValue)
                )
                .filter(Objects::nonNull)
                .collect(Collectors.joining(","));
    

    【讨论】:

      【解决方案3】:

      ComplexObject.java

      @Getter
      public class ComplexObject
      {
          private String globalCode;
      
          private List<Fields> fields;
      
      }
      

      Fields.java

      @Getter
      public class Fields
      {
          private String localCode;
          private List<FieldValues> fieldValues;
      }
      

      FieldValues.java

      @Getter
      public class FieldValues {
          private String value;
      
          private List<SubFields> subFields;
      
      }
      

      SubFields.java

      @Getter
      public class SubFields
      {
          private String localCode;
      
          private List<SubFieldValues> subFieldValues;
      
      }
      

      SubFieldValues.Java

      @Getter
      public class SubFieldValues{
          private String value;
      
      }
      

      主类

      public class Sol {
          public static void main(String[] args) throws JsonProcessingException {
      
              ObjectMapper objectMapper = new ObjectMapper();
              String json = "{\n" +
                      " \"globalCode\" : \"12\",\n" +
                      "  \"fields\" : [\n" +
                      "     {\n" +
                      "           \"localCode\" : \"72879\",\n" +
                      "           \"fieldValues\" : [\n" +
                      "                {\n" +
                      "                      \"value\" : null,\n" +
                      "                      \"subFields\" : [\n" +
                      "                           {\n" +
                      "                                 \"localCode\" : \"980\",\n" +
                      "                                 \"subFieldValues\" : [\n" +
                      "                                         {\n" +
                      "                                          \"value\" :  \"lon\"\n" +
                      "                                         }\n" +
                      "                                  ]\n" +
                      "                           },\n" +
                      "                            {\n" +
                      "                                 \"localCode\" : \"98\",\n" +
                      "                                 \"subFieldValues\" : [\n" +
                      "                                         {\n" +
                      "                                          \"value\" :  \"KPO\"\n" +
                      "                                         }\n" +
                      "                                  ]\n" +
                      "                           }\n" +
                      "                              \n" +
                      "\n" +
                      "                      ]\n" +
                      "                }       \n" +
                      "           ]\n" +
                      "     }\n" +
                      "  ]\n" +
                      "}";
              ComplexObject complexObject = objectMapper.readValue(json, ComplexObject.class);
      
      
              List<Fields> fields = complexObject.getFields();
              Stream.concat(
                      fields.stream().flatMap(field -> field.getFieldValues().stream()
                              .map(FieldValues::getValue)),
                      fields.stream()
                              .flatMap(field -> field.getFieldValues().stream())
                              .flatMap(fieldValue -> fieldValue.getSubFields().stream())
                              .flatMap(subField -> subField.getSubFieldValues().stream())
                              .map(SubFieldValues::getValue)
              )
                      .filter(Objects::nonNull)
                      .reduce((s, s2) -> s + "," + s2).ifPresent(System.out::println);
          }
      }
      

      输出:

      lon,KPO
      

      注意:

      • JSON 无效,您遗漏了几个逗号。我也修好了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 2017-09-26
        • 2016-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多