Mapping Nested Lists to Nested Maps in Java 8

user1697113 :
FamilyLegacy
   ParentList<Parent>

Parent //(Obj Class)
   ParentId // String ID
   ChildList<Child>  // List

Child
   ChildId
   GrandChildList<GrandChild>

GrandChild
    GrandChildId
   // Some GrandChild attribs    



{
  "parents": [
    {
      "Id": "P1",
      "parentName": "BigBob",
      "Child": [
        {
          "id": "C1",
          "name": "BOB",
          "grandChild": [
            {
              "grandChildId": "G1",
              "grandChildName": "John"
            },
            {
              "grandChildId": "G2",
              "grandChildName": "Doe"
            }
          ]
        },
        {
          "id": "C2",
          "name": "Marley",
          "grandChild": [
            {
              "grandChildId": "G3",
              "grandChildName": "Katty"
            },
            {
              "grandChildId": "G4",
              "grandChildName": "Perry"
            }
          ]
        }
      ]
    }
  ]
}

Outputs to ->

{
  "P1": {
    "name": "BigBob",
    "C1": {
      "name": "Bob",
      "G1": {
        "name": "John"
      },
      "G2": {
        "name": "Doe"
      }
    },
    "C2": {
      "name": "Marey",
      "G3": {
        "name": "Katty"
      },
      "G4": {
        "name": "Parry"
      }
    }
  }
}

Consider the above nested object to list structure. Is there a way to convert this structure to a nested Map such as

 Map<String,Map<String, Map<String,Map<String,GrandChild>>>>
ParentId -> map of Parents ->map of childs ->map of grand childs  keyed with respective IDs

For instance First Level Mapping

  Map<String, Parent> parentMap =
    FamilyLegacy.getParents().stream().collect(
                   Collectors.toMap(Parent::getParentId,Function.identity()));

I am having a hard time visualizing the mapping and nesting, would appreciate if there is a way to do it using direct grouping or map other than iterating individual list objects

Andronicus :

You can use Collectors.groupingBy to compose a nested map:

children.stream().collect(
    Collectors.groupingBy(
        gc -> gc.getChild().getParent().getFamilyLegacy().getId(),
        Collectors.groupingBy(
            gc -> gc.getChild().getParent().getId(),
            Collectors.groupingBy(
                gc -> gc.getChild().getId()))));

You can see where does the nesting come from by lambdas for getting keys.

The type will be then Map<String, Map<String, Map<String, GrandChild>>>. The first key fill be of FamilyLegacy, second of Parent, third from Child.

Edit:

Starting from FamilyLegacy you can use Collectors.toMap, like this:

familyLegacy.getParents().stream().collect(
    Collectors.toMap(
        p -> p.getId(),
        p -> p.getChildList().stream().collect(
            Collectors.toMap(
                c -> c.getId(),
                c -> c.getGrandChildList().stream().collect(
                    Collectors.toMap(
                        gc -> gc.getId(),
                        Function.identity()))))));

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=416578&siteId=1