0

I am aware of this post: Java - Merge JSON files ... but my problem is a bit different.

Let's say I have two JSON objects. First:

{
    "nodes":
    [
        {
            "id": "Main",
            "children":
            [
                {
                    "id": "C1",
                    "children":
                    [
                        {
                            "id": "C1.1",
                            "children":
                            []
                        }
                    ]
                }
            ]
        }
    ]
}

Second:

{
    "nodes":
    [
        {
            "id": "Main",
            "children":
            [
                {
                    "id": "C2",
                    "children":
                    [
                        {
                            "id": "C2.1",
                            "children":
                            []
                        }
                    ]
                },
                {
                    "id": "C3",
                    "children":
                    [
                        {
                            "id": "C3.1",
                            "children":
                            []
                        }
                    ]
                }
            ]
        }
    ]
}

And I would expect result to look like this:

{
    "nodes":
    [
        {
            "id": "Main",
            "children":
            [
                {
                    "id": "C1",
                    "children":
                    [
                        {
                            "id": "C1.1",
                            "children":
                            []
                        }
                    ]
                },
                {
                    "id": "C2",
                    "children":
                    [
                        {
                            "id": "C2.1",
                            "children":
                            []
                        }
                    ]
                },
                {
                    "id": "C3",
                    "children":
                    [
                        {
                            "id": "C3.1",
                            "children":
                            []
                        }
                    ]
                }
            ]
        }
    ]
}

Basically, I have multiple objects where "Main" node is constant but underneath there can be random number of different children and each child can have its own children.

I would like the code to produce one big object where parts duplicated across multiple objects are reduced to one.

Maybe there is a library that could do that for me? Maybe someone knows a simple solution for that...?

Thanks in advance for answers, I've been struggling to make this one work. There is probably too much code to post here and still is doesn't work correctly for every scenario.

  • It's hard to help without knowing where you're stuck. See https://stackoverflow.com/questions/49193854/merge-trees-on-equal-nodes or https://stackoverflow.com/questions/60335505/merge-json-tree-jackson – tgdavies Mar 31 '23 at 10:25

1 Answers1

0

I'm not clear about the complete issue, but this is a basic solution.

I'm guessing you are removing duplicates based on C1.1, C1.2, C1.3, etc, and my solution is based on that.

Define the classes

class Root {
    private List<MainClass> nodes;

    public List<MainClass> getNodes() {
        return nodes;
    }

    public void setNodes(List<MainClass> nodes) {
        this.nodes = nodes;
    }
}

class MainClass {
    private String id;  // Main
    private List<OuterClass> children;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public List<OuterClass> getChildren() {
        return children;
    }
    public void setChildren(List<OuterClass> children) {
        this.children = children;
    }
}

class OuterClass {
    private String id;  // C1
    private Set<InnerClass> children;   //  guessing the duplicate needs to be checked here
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public Set<InnerClass> getChildren() {
        return children;
    }
    public void setChildren(Set<InnerClass> children) {
        this.children = children;
    }
}

class InnerClass {
    private String id;  // C1.1
    private List<Child> children;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public List<Child> getChildren() {
        return children;
    }
    public void setChildren(List<Child> children) {
        this.children = children;
    }
    //  implement hashcode and equals for duplicate check
}

class Child {
    
}

I'm guessing your nodes will be having objects other than id as Main, so the main method would be like

public static void main(String[] args) {
        
        String json1 = "{" + 
                "    \"nodes\":" + 
                "    [" + 
                "        {" + 
                "            \"id\": \"Main\"," + 
                "            \"children\":" + 
                "            [" + 
                "                {" + 
                "                    \"id\": \"C1\"," + 
                "                    \"children\":" + 
                "                    [" + 
                "                        {" + 
                "                            \"id\": \"C1.1\"," + 
                "                            \"children\":" + 
                "                            []" + 
                "                        }" + 
                "                    ]" + 
                "                }" + 
                "            ]" + 
                "        }" + 
                "    ]" + 
                "}";
        
        String json2 = "{" + 
                "    \"nodes\":" + 
                "    [" + 
                "        {" + 
                "            \"id\": \"Main\"," + 
                "            \"children\":" + 
                "            [" + 
                "                {" + 
                "                    \"id\": \"C2\"," + 
                "                    \"children\":" + 
                "                    [" + 
                "                        {" + 
                "                            \"id\": \"C2.1\"," + 
                "                            \"children\":" + 
                "                            []" + 
                "                        }" + 
                "                    ]" + 
                "                }," + 
                "                {" + 
                "                    \"id\": \"C3\"," + 
                "                    \"children\":" + 
                "                    [" + 
                "                        {" + 
                "                            \"id\": \"C3.1\"," + 
                "                            \"children\":" + 
                "                            []" + 
                "                        }" + 
                "                    ]" + 
                "                }" + 
                "            ]" + 
                "        }" + 
                "    ]" + 
                "}";
        
        Root rootMain = (Root) jsonToObject(json1, Root.class);
        Root rootSub = (Root) jsonToObject(json2, Root.class);
        
        MainClass main = rootMain.getNodes().stream().filter(node -> "Main".equals(node.getId())).findFirst().get();
        MainClass sub = rootSub.getNodes().stream().filter(node -> "Main".equals(node.getId())).findFirst().get();
        
        main.getChildren().addAll(sub.getChildren());
        
        System.out.println(Globals.asJsonString(rootMain));
    }

This is the method to convert JSON to an object

public static <T> Object jsonToObject(final String json, Class<T> type) {
    try {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(json, type);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
Arun Sudhakaran
  • 2,167
  • 4
  • 27
  • 52