如何在Java中以特定方式订购JSON列号

时间:2019-03-23 19:55:31

标签: java json spring-boot

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

CSV.File

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
            }
         ]
      ]
   }
]

2 个答案:

答案 0 :(得分:1)

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

我想出的算法是这样的:

  1. 选择一个元素并检查它是否是根之一的后代。 如果不是,请将其添加到根目录列表中。检查是否存在 根实际上是此元素的后代,并将它们分配为 如果是这样的话(例如,如果我们在输入中输入12,然后输入1, 应该将12移为1的子​​级-尽管可能不完全是 在这种特定情况下,如果我们的输入进行了排序(例如1将 总是在12之前,123之前等)请注意,由于输入的排序,该部分是可选的,但是如果您使用未排序的输入,则此部分会不完整(如果先输入12后接1234,然后再输入123,则不会产生正确的结果-1234和123均为12的子代但这是不正确的-1234应该成为123的子级,而不是直接成为12)。这是您完成作业的作业;-)
  2. 如果它是某些东西的后代 根-找到它的后代也可能是根的子代。如果 没有这样的-将其分配为直接子代。如果有一个, 将其视为潜在的父母,但同时还要检查其子女 潜在的父母,等等。

这是一个完整的工作解决方案,可以按您期望的那样生成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));
    }
}

答案 1 :(得分:0)

创建一个具有两个字段的响应对象。

.386p

GDT struct
limit_0_15 word ?
base_0_15  word ?
base_16_23 byte ?
access_byt byte ?
fl_limit   byte ?
base_24_31 byte ?
GDT ends

main_data segment use16
idt_start:
    db 800h dup (?)
idt_info:
    dw 2048
    dd idt_start

gdt_start:
nul_gdt GDT <0,0,0,0,0,0>
c32_gdt GDT <0,0,0,0,0,0>
d32_gdt GDT <0,0,0,0,0,0>
gdt_info:
    dw gdt_info - gdt_start - 1
    dd gdt_start

main_data ends

main_code segment use16
assume cs:main_code, ds:main_data, ss:stack16
_start:

mov  ax,main_data
mov  ds,ax
mov  ax,code16
mov  es,ax
call es:[Check_A20]
call es:[Set_A20]
call es:[Check_A20]
call es:[Create_GDT]

mov  bx,gdt_info
lgdt fword ptr[bx]

mov  bx,idt_info
lidt fword ptr[bx]

mov  eax,cr0
or   eax,1
mov  cr0,eax

jmp clear_prefetch_queue
nop
nop
clear_prefetch_queue:

mov  eax,0ffffh
mov  ebx,0fh
div  ebx

exit:
mov  ah,4ch
int  21h
main_code ends



code16 segment use16

Wait_8042_command proc ; wait for the kbd controller to get ready to take in commands
in   al,64h
test al,2
jnz  Wait_8042_command
ret
Wait_8042_command endp

Wait_8042_data proc   ; wait for the kbd controller to get ready to take in data
in   al,64h
test al,1
jz   Wait_8042_data
ret
Wait_8042_data endp

Check_A20 proc
pushf
push ds
push es
push di
push si

cli
xor  ax,ax
mov  es,ax
mov  di,500h
not  ax
mov  ds,ax
mov  si,510h

mov  al,byte ptr es:[di]
push ax
mov  al,byte ptr ds:[si]
push ax

mov  byte ptr es:[di],0
mov  byte ptr ds:[si],0ffh
cmp  byte ptr es:[di],0ffh

pop  ax
mov  byte ptr ds:[si],al
pop  ax
mov  byte ptr es:[di],al

mov  ax,0
je   check_a20_exit
mov  ax,1

check_a20_exit:
pop  si
pop  di
pop  es
pop  ds
popf
retf
Check_A20 endp

Set_A20 proc
cli
call Wait_8042_command
mov  al,0ADh             ;set command to disable kbd
out  64h,al

call Wait_8042_command
mov  al,0d0h
out  64h,al              ;read from input

call Wait_8042_data
in   al,60h              ;read input from kbd
push ax

call Wait_8042_command
mov  al,0d1h             ;write to output
out  64h,al

call Wait_8042_command
pop  ax
or   al,2
out  60h,al

call Wait_8042_command
mov  al,0AEh            ;enable kbd controller
out  64h,al

call Wait_8042_command
sti
retf
Set_A20 endp

Create_GDT proc
push ds
mov  ax,main_data
mov  ds,ax

;NULL Descriptor
;mov  cx,4
;rep  stosw
;code32 gdt initialized
mov  c32_gdt.limit_0_15, 0ffffh
mov  c32_gdt.base_0_15,  0h
mov  c32_gdt.base_16_23, 0h
mov  c32_gdt.access_byt, 9ah
mov  c32_gdt.fl_limit,   0cfh
mov  c32_gdt.base_24_31, 0h
;data32 gdt initialized
mov  d32_gdt.limit_0_15, 0ffffh
mov  d32_gdt.base_0_15,  0h
mov  d32_gdt.base_16_23, 0h
mov  d32_gdt.access_byt, 92h
mov  d32_gdt.fl_limit,   0cfh
mov  d32_gdt.base_24_31, 0h

pop  ds
retf
Create_GDT endp


code16 ends


code32 segment use32
mov  eax,0ffffh ;test garbage
mov  ebx,0fh
div  ebx
code32 ends

data32 segment use32

data32 ends


stack16 segment stack use16
    dw 200h dup (?)
stack16 ends

end _start

该课程将为您提供想要的东西。