java - 如何在 Java 中以特定方式对 JSON 列号进行排序

标签 java json spring-boot

我在 Spring Boot 中开发了一个应用程序。用户可以上传 CSV 文件,其中包含数字和代码列。在 Java 代码中,我能够获取数字列。

CSV.文件

number   code
12
121
122
123
1211
1212
1231
124

我的目标和回应将给出:

响应 - 目标

json: [{ number: 12, 
    child: [{number: 121, 
       child: [{number: 1211 }, { number: 1212 }]
    }] 
}, {number: 122 },
   {number: 123, child:[{number: 1231}] }.....etc
]

如何在 Java 中按父级和子级排序此 JSON 结构?例如。 12 是 121 的父级,121 是 1211 和 1212 的父级。

更新:

输入值:

12
121
122
123
1211
1212
1231
14
141
142
1411
25
251
2511
2512
252
253

响应输出

    response: [
   {
      "number": 12,
      "child": [
         {
            "number": 121,
            "child": [
               {
                  "number": 1211
               },
               {
                  "number": 1212
               }
            ]
         },
         [
            {
               "number": 122
            }
         ],
         [
            {
               "number": 123,
               "child": [
                  {
                     "number": 1231
                  }
               ]
            }
         ]
      ]
   },
   {
      "number": 14,
      "child": [
         {
            "number": 141,
            "child": [
               {
                  "number": 1411
               }
            ]
         },
         [
            {
               "number": 142
            }
         ]
      ]
   },
   {
      "number": 25,
      "child": [
         {
            "number": 251,
            "child": [
               {
                  "number": 2511
               },
               {
                  "number": 2512
               }
            ]
         },
         [
            {
               "number": 252
            }
         ],
         [
            {
               "number": 253
            }
         ]
      ]
   }
]

最佳答案

这并不是真正的 Java 或 JSON 问题。简而言之,您的问题是 - 如何将值列表组装成知道列表元素之间的祖先-后代关系的树结构。

我想出的算法是这样的:

  1. 选择一个元素并检查它是否是其中一个根的后代。 如果不是 - 将其添加到根列表中。检查是否存在任何 根实际上是该元素的后代,并将它们分配为 如果它们是这样的话(例如,如果我们输入中有 12 个,然后我们有 1 个 应该将 12 移动为 1 的子级 - 尽管这可能不完全是 如果我们的输入已排序,则在这种特定情况下是必要的,例如1 会 总是在 12 之前,在 123 之前,等等)。请注意,由于输入排序,这部分是可选的,但如果您使用未排序的输入,则有些不完整(如果我们有 12 后跟 1234,然后是 123,则不会产生正确的结果 - 1234 和 123 都将是 12 的子级,但这是不正确的 - 1234 应该成为 123 的子级,而不是直接 12)。这将是你需要完成的作业;-)
  2. 如果它是某个人的后代 root - 找到根的子项,它也可能是其后代。如果 没有这样的 - 将其指定为直接子代。如果有的话, 将其视为潜在的父项,但同时还要检查它的子项 对于潜在的父级,递归地依此类推。

这是一个完整的工作解决方案,可以按照您的预期生成 JSON:

package tmpjavaproj;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

public class Test {

    public static class Node implements Comparable<Node> {
        public int number;
        public List<Node> child; // Although this should actually be called children, not child

        public int hashCode() {
            return number;
        }

        public boolean equals(Node node) {
            return number == node.number;
        }

        public int compareTo(Node node) {
            return number - node.number;
        }
    }

    public static void main(String[] args) throws Exception {
        String[] inputs = { "12", "121", "122", "123", "1211", "1212", "1231", "14", "141", "142", "1411", "25", "251", "2511", "2512", "252", "253" };

        Set<Node> roots = new TreeSet<>();

        for (String input : inputs) {
            Node node = new Node();
            node.number = Integer.parseInt(input);

            Node root = null;
            for (Node rootCandidate : roots) {
                if (input.startsWith(String.valueOf(rootCandidate.number))) {
                    root = rootCandidate;
                    break;
                }
            }
            if (root == null) {
                List<Node> rootsToChildren = new ArrayList<>();
                for (Node aRoot : roots) {
                    if (String.valueOf(aRoot.number).startsWith(String.valueOf(node.number))) {
                        rootsToChildren.add(aRoot);
                    }
                }
                if (!rootsToChildren.isEmpty()) {
                    node.child = rootsToChildren;
                    roots.removeAll(rootsToChildren);
                }
                roots.add(node);
            } else {
                Node parentCandidate = root;
                while (root != null) {
                    root = null;
                    if (parentCandidate.child != null) {
                        for (Node child : parentCandidate.child) {
                            if (input.startsWith(String.valueOf(child.number))) {
                                parentCandidate = child;
                                root = child;
                            }
                        }
                    }
                }
                if (parentCandidate.child == null) {
                    parentCandidate.child = new ArrayList<>();
                }
                parentCandidate.child.add(node);
            }
        }

        Map<String, Set<Node>> response = new HashMap<>();
        response.put("response", roots);
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.setSerializationInclusion(Include.NON_NULL);
        System.out.println(mapper.writeValueAsString(response));
    }
}

关于java - 如何在 Java 中以特定方式对 JSON 列号进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55317780/

相关文章:

java - 我怎样才能知道点击了哪个按钮?

java - 反转单链表只会输出第一个条目(java

javascript - 以原始顺序迭代 jQuery JSON 对象

spring-boot - 打开 "Whitelabel Error Page"时获取 "/actuator/mappings"

java - 请求映射和静态字段

java - 如何将字符串转换为对象并使用 Jackson 检索值

java - 如何使用 hibernate 和 MySQL 在 java 中创建单页应用程序 (SPA)

javascript - 通过 ReduxReducer 中的键附加到数组访问

javascript - 从 HTML 脚本向另一个域中的 Node.JS 应用程序发出 POST JSON 请求

java - spring.datasource.username 和 spring.datasource.data-username 之间的区别