【问题标题】:Grouping by Unique ID for JSON Array按 JSON 数组的唯一 ID 分组
【发布时间】:2023-02-18 02:55:08
【问题描述】:

块引用

我有以下 JSON 输入请求,必须按以下方式分组ID范围。

输入 :

[
    {
        "ID": "1234",
        "CustomerName": "KUMAR",
        "BranchName": "HARBOUR",
        "SchemeName": "GOLD",
        "MobileNumber": "123456789",
        "CustomerType": "PRIMARY",
        "DedupeFound" : "NO"
        
    },
    {
        "ID": "1234",
        "CustomerName": "SEAN",
        "BranchName": "HARBOUR",
        "SchemeName": "GOLD",
        "MobileNumber": "123456789",
        "CustomerType": "SECONDARY",
        "DedupeFound" : "YES"
    },
    {
        "ID": "5678",
        "CustomerName": "MARK",
        "BranchName": "CANTONMENT",
        "SchemeName": "DIAMOND",
        "MobileNumber": "123456789",
        "CustomerType": "PRIMARY",
        "DedupeFound" : "NO"
    },
    {
        "ID": "5678",
        "CustomerName": "STEVE",
        "BranchName": "CANTONMENT",
        "SchemeName": "DIAMOND",
        "MobileNumber": "123456789",
        "CustomerType": "SECONDARY",
        "DedupeFound" : "YES"
    }
]

上面的请求需要按照下面的方式进行改造

  1. 首先根据 ID 标签对记录进行分组,只需要显示主 ID 的详细信息
  2. 在 ID 记录详细信息中。我有两个客户的 DedupeDetails 数组。

    输出

    [
        {
            "ID": "1234",
            "CustomerName": "KUMAR",           // Only Primary Customer Details for the 
            "BranchName": "HARBOUR",           //  ID Tag to be displayed here
            "SchemeName": "GOLD",
            "MobileNumber": "123456789"
            "DedupeDetails": [
                {
                    "CustomerType": "PRIMARY"
                    "CustomerName": "KUMAR",
                    "DedupeFound" : "NO"
                },
                {
                    "CustomerType": "SECONDARY"
                    "CustomerName": "SEAN",
                    "DedupeFound" : "YES"
                }
            ]
        },
        {
            "ID": "5678",
            "CustomerName": "MARK",
            "BranchName": "CANTONMENT",
            "SchemeName": "DIAMOND",
            "MobileNumber": "123456789"
            "DedupeDetails": [
                {
                    "CustomerType": "PRIMARY"
                    "CustomerName": "MARK",
                    "DedupeFound" : "NO"
                },
                {
                    "CustomerType": "SECONDARY"
                    "CustomerName": "STEVE",
                    "DedupeFound" : "YES"
                }
            ]
        }
    ]
    

    我已经开始使用 apache camel 中的 java 代码。我能够成功地将 json 字符串映射到对象列表。我仍然对如何进行分组以实现输出一无所知。

    注意:我是 java 的新手。强烈建议任何建议/更正。

    爪哇

    package com.mycompany.Login;
    
    import java.util.List;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Date;
    import java.util.HashMap;
    import java.sql.Timestamp;
    import java.io.File;
    import java.io.PrintWriter;
    import java.sql.Time;
    import com.mycompany.Login.*;
    import org.apache.camel.Exchange;
    import org.apache.camel.Processor;
    import com.fasterxml.jackson.databind.DeserializationFeature;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.mycompany.Dedupe.DedupeRoot.DedupeRes;
    
    
    
    
    public class LoginMapping implements Processor{
        public void process(Exchange ex)throws Exception{ 
        
            try {   
            
               
                String responseString = {Input mentioned in post};          
                ObjectMapper mapper = new ObjectMapper();
                mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);         
                List<DedupeRes> dedupe = Arrays.asList(mapper.readValue(responseString, DedupeRes[].class));  
                int total = dedupe.size();          
                if (total > 0)
                {               
                    for (int i = 0; i < total; i++) {                   
                        
                    }               
                }
        
         ex.getIn().setBody(responseString);
            }       
            catch(Exception e) {
                ex.getIn().setHeader("ExpMsg", "Undefined");
                throw e;
            }   
        
    }
    }
    
    

【问题讨论】:

    标签: java


    【解决方案1】:

    完整的代码实现,试试吧。

    public class T {
    
        private static final ObjectMapper mapper = new ObjectMapper();
    
        static {
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        }
    
        public static <T> List<T> parseObjectList(String json, Class<T> clazz) {
            try {
                return mapper.readValue(
                        json,
                        TypeFactory.defaultInstance().constructParametricType(ArrayList.class, clazz)
                );
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        public static <T> String toJsonString(T t) {
            try {
                return mapper.writeValueAsString(t);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        public static void main(String[] args) {
            try {
                String responseString = "[{"ID":"1234","CustomerName":"KUMAR","BranchName":"HARBOUR","SchemeName":"GOLD","MobileNumber":"123456789","CustomerType":"PRIMARY","DedupeFound":"NO"},{"ID":"1234","CustomerName":"SEAN","BranchName":"HARBOUR","SchemeName":"GOLD","MobileNumber":"123456789","CustomerType":"SECONDARY","DedupeFound":"YES"},{"ID":"5678","CustomerName":"MARK","BranchName":"CANTONMENT","SchemeName":"DIAMOND","MobileNumber":"123456789","CustomerType":"PRIMARY","DedupeFound":"NO"},{"ID":"5678","CustomerName":"STEVE","BranchName":"CANTONMENT","SchemeName":"DIAMOND","MobileNumber":"123456789","CustomerType":"SECONDARY","DedupeFound":"YES"}]";
                List<DedupeRes> list = parseObjectList(responseString, DedupeRes.class);
                if (list != null && !list.isEmpty()) {
                    Map<String, List<DedupeRes>> map = list.stream().collect(Collectors.groupingBy(DedupeRes::getID));
                    List<Res> resList = new ArrayList<>();
                    map.forEach((k, v) -> resList.add(listToRes(v)));
                    responseString = toJsonString(resList);
                    System.out.println(responseString);
                }
            } catch (Exception e) {
                // xx
                e.printStackTrace();
            }
        }
    
        private static Res listToRes(List<DedupeRes> list) {
            Res res = new Res();
            res.setDedupeDetails(new ArrayList<>());
            for (DedupeRes dedupeRes : list) {
                if (Objects.equals("PRIMARY", dedupeRes.getCustomerType())) {
                    // if you used spring -> BeanUtils.copyProperties(dedupeRes, res);
                    res.setID(dedupeRes.getID());
                    res.setBranchName(dedupeRes.getBranchName());
                    res.setCustomerName(dedupeRes.getCustomerName());
                    res.setMobileNumber(dedupeRes.getMobileNumber());
                    res.setSchemeName(dedupeRes.getSchemeName());
                }
                DedupeDetails details = new DedupeDetails();
                //
                BeanUtils.copyProperties(dedupeRes, details);
                res.getDedupeDetails().add(details);
            }
            return res;
        }
    
        @Data
        private static class DedupeRes {
            @JsonProperty("ID")
            private String ID;
            @JsonProperty("CustomerName")
            private String CustomerName;
            @JsonProperty("BranchName")
            private String BranchName;
            @JsonProperty("SchemeName")
            private String SchemeName;
            @JsonProperty("MobileNumber")
            private String MobileNumber;
            @JsonProperty("CustomerType")
            private String CustomerType;
            @JsonProperty("DedupeFound")
            private String DedupeFound;
        }
    
        @Data
        private static class Res {
            @JsonProperty("ID")
            private String ID;
            @JsonProperty("CustomerName")
            private String CustomerName;
            @JsonProperty("BranchName")
            private String BranchName;
            @JsonProperty("SchemeName")
            private String SchemeName;
            @JsonProperty("MobileNumber")
            private String MobileNumber;
            @JsonProperty("dedupeDetails")
            private List<DedupeDetails> dedupeDetails;
        }
    
        @Data
        private static class DedupeDetails {
            @JsonProperty("CustomerType")
            private String CustomerType;
            @JsonProperty("CustomerName")
            private String CustomerName;
            @JsonProperty("DedupeFound")
            private String DedupeFound;
        }
    }
    
    

    领事。

    [{"ID":"1234","CustomerName":"KUMAR","BranchName":"HARBOUR","SchemeName":"GOLD","MobileNumber":"123456789","dedupeDetails":[{"CustomerType":"PRIMARY","CustomerName":"KUMAR","DedupeFound":"NO"},{"CustomerType":"SECONDARY","CustomerName":"SEAN","DedupeFound":"YES"}]},{"ID":"5678","CustomerName":"MARK","BranchName":"CANTONMENT","SchemeName":"DIAMOND","MobileNumber":"123456789","dedupeDetails":[{"CustomerType":"PRIMARY","CustomerName":"MARK","DedupeFound":"NO"},{"CustomerType":"SECONDARY","CustomerName":"STEVE","DedupeFound":"YES"}]}]
    

    【讨论】:

      【解决方案2】:

      首先你必须创建DedupeDetail类:

      public class DedupeDetail {
      
          String CustomerType;
          String CustomerName;
          String DedupeFound;
      
          public DedupeDetail(String customerType, String customerName, String dedupeFound) {
              CustomerType = customerType;
              CustomerName = customerName;
              DedupeFound = dedupeFound;
          }
      }
      

      然后用转换器创建DedupeResultFinal

      public class DedupeResultFinal {
      
          String ID;
          String CustomerName;
          String BranchName;
          String SchemeName;
          String MobileNumber;
          List<DedupeDetail> DedupeDetails;
      
          public DedupeResultFinal() {
          }
      
          public DedupeResultFinal(List<DedupeDetail> dedupeDetails) {
              DedupeDetails = dedupeDetails;
          }// ... other constructor and getter and setter
      
          public static DedupeResultFinal convertToFinal(HashMap<String, String> dedupeRes){
              DedupeResultFinal dedupeResultFinal = new DedupeResultFinal();
      
              dedupeResultFinal.setBranchName(dedupeRes.get("BranchName"));
              dedupeResultFinal.setCustomerName(dedupeRes.get("CustomerName"));
              dedupeResultFinal.setID(dedupeRes.get("ID"));
              dedupeResultFinal.setMobileNumber(dedupeRes.get("MobileNumber"));
              dedupeResultFinal.setSchemeName(dedupeRes.get("SchemeName"));
      
              return dedupeResultFinal;
      
          }
      }
      

      然后你的方法必须是这样的:

         public static void main(String[] args) {
              try {
      
                  String responseString = {Input mentioned in post};
                  ObjectMapper mapper = new ObjectMapper();
                  mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                  List<HashMap<String, String>> dedupe = mapper.readValue(responseString, new ArrayList<String>().getClass());
                  Map<String, DedupeResultFinal> map = new HashMap<>();
      
                  for (HashMap<String, String> dedupeRes : dedupe) {
                      if (map.get(dedupeRes.get("ID")) != null){
                          DedupeDetail dedupeDetail = new DedupeDetail(dedupeRes.get("CustomerType"), dedupeRes.get("CustomerName"), dedupeRes.get("DedupeFound"));
                          map.get(dedupeRes.get("ID")).getDedupeDetails().add(dedupeDetail);
                      }else {
                          DedupeDetail dedupeDetail =  new DedupeDetail(dedupeRes.get("CustomerType"), dedupeRes.get("CustomerName"), dedupeRes.get("DedupeFound"));
                          DedupeResultFinal dedupeResultFinal = DedupeResultFinal.convertToFinal(dedupeRes);
                          List<DedupeDetail> dedupeDetails = new ArrayList<>();
                          dedupeDetails.add(dedupeDetail);
                          dedupeResultFinal.setDedupeDetails(dedupeDetails);
      
                          map.put(dedupeRes.get("ID"), dedupeResultFinal);
                      }
                  }
      
                 List<DedupeResultFinal> finalDedup = map.values().stream().collect(Collectors.toList());
      
                  System.out.println(finalDedup);
              }
              catch(Exception e) {
                  e.printStackTrace();
              }
          }
      

      【讨论】:

      • 感谢 hani 的解决方案。但是我在尝试构建 jar 时遇到了这个错误。不兼容的类型:java.util.List<java.lang.Object> 无法转换为 java.util.List<com.Veritas.Test.DedupeResultFinal>
      • 好吧,你先把 List 放在上层,然后再转换到下层。所以当你得到列表时,你的列表是 List<Object> 并且在迭代之后,你必须将每个成员转换为 DedupeResultFinal。
      【解决方案3】:

      您可以使用 JSON 库,例如约森做改造。

      https://github.com/octomix/josson

      反序列化

      Josson josson = Josson.fromJsonString(yourJsonString);
      

      方法一

      从根节点开始查找每组的主记录。

      JsonNode node = josson.getNode(
          "group(ID, DedupeDetails:map(CustomerType, CustomerName, DedupeFound))@" +
          ".let($id:ID, $pri:$.[ID=$id & CustomerType='PRIMARY'])" +
          ".field($pri.CustomerName, $pri.BranchName, $pri.SchemeName, $pri.MobileNumber)");
      
      System.out.println(node.toPrettyString());
      

      方法二

      查找每个组中的主要记录。

      JsonNode node = josson.getNode(
          "group(ID)@" +
          ".let($pri: elements[CustomerType='PRIMARY'])" +
          ".field($pri.CustomerName, $pri.BranchName, $pri.SchemeName, $pri.MobileNumber," +
          "       elements:, DedupeDetails:elements.map(CustomerType, CustomerName, DedupeFound))");
      
      System.out.println(node.toPrettyString());
      

      方法三

      使用 mergeObjects() 而不是 let() 来完成任务。

      JsonNode node = josson.getNode(
          "group(ID)@" +
          ".mergeObjects(" +
          "  elements[CustomerType='PRIMARY'].map(ID, CustomerName, BranchName, SchemeName, MobileNumber)," +
          "  map(DedupeDetails:elements.map(CustomerType, CustomerName, DedupeFound))" +
          ")");
      
      System.out.println(node.toPrettyString());
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-07
        • 2021-05-05
        • 2022-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-31
        • 2018-10-07
        相关资源
        最近更新 更多