Search code examples
javaarrayscollectionsjava-stream

How to split objects based on an element from a nested object present in an ArrayList in Java?


I have the following list of objects (showing only one object in an array for example). How to do I split the users list into different objects with same original object using Java. I have given the result I am getting from the database and the result am expecting after processing in Java.

As you can see in the result I am expecting in the given expected JSON , the objects all remain the same except the users array list in each object. We have to split the array in terms of "parent_user_id" in all the objects in users array, so common objects with same "parent_user_id" will be in one object as a whole.

Result am getting from DB:

[
    {
        "_id" : "63a8808652f40e1d48a3d1d7",
        "name" : "A",
        "description" : null,
        "users" : [
            {
                "id" : "63a8808c52f40e1d48a3d1da",
                "owner" : "John Doe",
                "purchase_date" : "2022-12-25",
                "status" : "active",
                "parent_user_id" : "63a8808c52f40e1d48a3d1da"
            },
            {
                "id" : "63a880a552f40e1d48a3d1dc",
                "owner" : "John Doe 1",
                "purchase_date" : "2022-12-25",
                "parent_user_id" : "63a8808c52f40e1d48a3d1da"
            },
            {
                "id" : "63a880f752f40e1d48assddd",
                "owner" : "John Doe 2",
                "purchase_date" : "2022-12-25",
                "parent_user_id" : "63a8808c52f40e1d48a3d1da"
            },
            {
                "id" : "63a880f752f40e1d48a3d207",
                "owner" : "John Doe 11",
                "dt" : "2022-12-25",
                "status" : "inactive",
                "parent_user_id" : "63a880f752f40e1d48a3d207"
            },
            {
                "id" : "63a880f752f40e1d48agfmmb",
                "owner" : "John Doe 112",
                "dt" : "2022-12-25",
                "status" : "active",
                "parent_user_id" : "63a880f752f40e1d48agfmmb"
            },
            {
                "id" : "63a880f752f40e1d48agggg",
                "owner" : "John SS",
                "dt" : "2022-12-25",
                "status" : "inactive",
                "parent_user_id" : "63a880f752f40e1d48agggg"
            },
            {
                "id" : "63a880f752f40e1d487777",
                "owner" : "John SS",
                "dt" : "2022-12-25",
                "parent_user_id" : "63a880f752f40e1d48agggg"
            }
        ]
    }
]

Result I need after processing in Java:

[
  {
    "_id": "63a8808652f40e1d48a3d1d7",
    "name": "A",
    "description": null,
    "users": [
      {
        "id": "63a8808c52f40e1d48a3d1da",
        "owner": "John Doe",
        "purchase_date": "2022-12-25",
        "status": "active",
        "parent_user_id": "63a8808c52f40e1d48a3d1da"
      },
      {
        "id": "63a880a552f40e1d48a3d1dc",
        "owner": "John Doe 1",
        "purchase_date": "2022-12-25",
        "parent_user_id": "63a8808c52f40e1d48a3d1da"
      },
      {
        "id": "63a880f752f40e1d48assddd",
        "owner": "John Doe 2",
        "purchase_date": "2022-12-25",
        "parent_user_id": "63a8808c52f40e1d48a3d1da"
      }
    ]
  },
  {
    "_id": "63a8808652f40e1d48a3d1d7",
    "name": "A",
    "description": null,
    "users": [
      {
        "id": "63a880f752f40e1d48a3d207",
        "owner": "John Doe 11",
        "dt": "2022-12-25",
        "status": "inactive",
        "parent_user_id": "63a880f752f40e1d48a3d207"
      }
    ]
  },
  {
    "_id": "63a8808652f40e1d48a3d1d7",
    "name": "A",
    "description": null,
    "users": [
      {
        "id": "63a880f752f40e1d48agfmmb",
        "owner": "John Doe 112",
        "dt": "2022-12-25",
        "status": "active",
        "parent_user_id": "63a880f752f40e1d48agfmmb"
      }
    ]
  },
  {
    "_id": "63a8808652f40e1d48a3d1d7",
    "name": "A",
    "description": null,
    "users": [
      {
        "id": "63a880f752f40e1d48agggg",
        "owner": "John SS",
        "dt": "2022-12-25",
        "status": "inactive",
        "parent_user_id": "63a880f752f40e1d48agggg"
      },
      {
        "id": "63a880f752f40e1d487777",
        "owner": "John SS",
        "dt": "2022-12-25",
        "parent_user_id": "63a880f752f40e1d48agggg"
      }
    ]
  }
]

Solution

  • You can use JSON library such as Josson to do the transformation.

    https://github.com/octomix/josson

    Deserialization

    Josson josson = Josson.fromJsonString(
        "[" +
        "    {" +
        "        \"_id\": \"63a8808652f40e1d48a3d1d7\"," +
        "        \"name\": \"A\"," +
        "        \"description\": null," +
        "        \"users\": [" +
        "            {" +
        "                \"id\": \"63a8808c52f40e1d48a3d1da\"," +
        "                \"owner\": \"John Doe\"," +
        "                \"purchase_date\": \"2022-12-25\"," +
        "                \"status\": \"active\"," +
        "                \"parent_user_id\": \"63a8808c52f40e1d48a3d1da\"" +
        "            }," +
        "            {" +
        "                \"id\": \"63a880a552f40e1d48a3d1dc\"," +
        "                \"owner\": \"John Doe 1\"," +
        "                \"purchase_date\": \"2022-12-25\"," +
        "                \"parent_user_id\": \"63a8808c52f40e1d48a3d1da\"" +
        "            }," +
        "            {" +
        "                \"id\": \"63a880f752f40e1d48assddd\"," +
        "                \"owner\": \"John Doe 2\"," +
        "                \"purchase_date\": \"2022-12-25\"," +
        "                \"parent_user_id\": \"63a8808c52f40e1d48a3d1da\"" +
        "            }," +
        "            {" +
        "                \"id\": \"63a880f752f40e1d48a3d207\"," +
        "                \"owner\": \"John Doe 11\"," +
        "                \"dt\": \"2022-12-25\"," +
        "                \"status\": \"inactive\"," +
        "                \"parent_user_id\": \"63a880f752f40e1d48a3d207\"" +
        "            }," +
        "            {" +
        "                \"id\": \"63a880f752f40e1d48agfmmb\"," +
        "                \"owner\": \"John Doe 112\"," +
        "                \"dt\": \"2022-12-25\"," +
        "                \"status\": \"active\"," +
        "                \"parent_user_id\": \"63a880f752f40e1d48agfmmb\"" +
        "            }," +
        "            {" +
        "                \"id\": \"63a880f752f40e1d48agggg\"," +
        "                \"owner\": \"John SS\"," +
        "                \"dt\": \"2022-12-25\"," +
        "                \"status\": \"inactive\"," +
        "                \"parent_user_id\": \"63a880f752f40e1d48agggg\"" +
        "            }," +
        "            {" +
        "                \"id\": \"63a880f752f40e1d487777\"," +
        "                \"owner\": \"John SS\"," +
        "                \"dt\": \"2022-12-25\"," +
        "                \"parent_user_id\": \"63a880f752f40e1d48agggg\"" +
        "            }" +
        "        ]" +
        "    }," +
        "    {" +
        "        \"_id\": \"111111111111111111111111\"," +
        "        \"name\": \"B\"," +
        "        \"users\": [" +
        "            {" +
        "                \"id\": \"22222222222222222222222\"," +
        "                \"owner\": \"John XX\"," +
        "                \"purchase_date\": \"2022-12-25\"," +
        "                \"status\": \"active\"," +
        "                \"parent_user_id\": \"22222222222222222222222\"" +
        "            }" +
        "        ]" +
        "    }" +
        "]");
        
    

    Transformation

    JsonNode node = josson.getNode(
        "[]@" + // 1
        ".users" + // 2
        ".group(parent_user_id)" + // 3
        ".map(..._id, ...name, ...description, users:elements)" + // 4
        ".@flatten()"); // 5
    System.out.println(node.toPrettyString());
    
    1. Divert each element to separate branches
    2. Proceed to node users
    3. Group by parent_user_id
    4. Map a new object, get _id/name/description from 2 steps back, and rename elements to users
    5. Merge all branch results into a single array and then flatten the array

    Output

    [ {
      "_id" : "63a8808652f40e1d48a3d1d7",
      "name" : "A",
      "description" : null,
      "users" : [ {
        "id" : "63a8808c52f40e1d48a3d1da",
        "owner" : "John Doe",
        "purchase_date" : "2022-12-25",
        "status" : "active",
        "parent_user_id" : "63a8808c52f40e1d48a3d1da"
      }, {
        "id" : "63a880a552f40e1d48a3d1dc",
        "owner" : "John Doe 1",
        "purchase_date" : "2022-12-25",
        "parent_user_id" : "63a8808c52f40e1d48a3d1da"
      }, {
        "id" : "63a880f752f40e1d48assddd",
        "owner" : "John Doe 2",
        "purchase_date" : "2022-12-25",
        "parent_user_id" : "63a8808c52f40e1d48a3d1da"
      } ]
    }, {
      "_id" : "63a8808652f40e1d48a3d1d7",
      "name" : "A",
      "description" : null,
      "users" : [ {
        "id" : "63a880f752f40e1d48a3d207",
        "owner" : "John Doe 11",
        "dt" : "2022-12-25",
        "status" : "inactive",
        "parent_user_id" : "63a880f752f40e1d48a3d207"
      } ]
    }, {
      "_id" : "63a8808652f40e1d48a3d1d7",
      "name" : "A",
      "description" : null,
      "users" : [ {
        "id" : "63a880f752f40e1d48agfmmb",
        "owner" : "John Doe 112",
        "dt" : "2022-12-25",
        "status" : "active",
        "parent_user_id" : "63a880f752f40e1d48agfmmb"
      } ]
    }, {
      "_id" : "63a8808652f40e1d48a3d1d7",
      "name" : "A",
      "description" : null,
      "users" : [ {
        "id" : "63a880f752f40e1d48agggg",
        "owner" : "John SS",
        "dt" : "2022-12-25",
        "status" : "inactive",
        "parent_user_id" : "63a880f752f40e1d48agggg"
      }, {
        "id" : "63a880f752f40e1d487777",
        "owner" : "John SS",
        "dt" : "2022-12-25",
        "parent_user_id" : "63a880f752f40e1d48agggg"
      } ]
    }, {
      "_id" : "111111111111111111111111",
      "name" : "B",
      "users" : [ {
        "id" : "22222222222222222222222",
        "owner" : "John XX",
        "purchase_date" : "2022-12-25",
        "status" : "active",
        "parent_user_id" : "22222222222222222222222"
      } ]
    } ]