Home > Mobile >  To get the names of all the Items in the hierarchy using streams
To get the names of all the Items in the hierarchy using streams

Time:04-12

class ParentItem {
    String itemName;  //I want to get this property for all the objects in hierarchy
    Integer itemCode;
    List<ParentItem> childItem;
}

I want to get the names of the All Items(ParentItem name, ChildItem name, GrandChildItemName) using streams, how to achieve this? Assume the ChildItem also has a Child which means the ParentItem has a GrandChild! So there are 3 levels of Nesting. How to achieve this?

CodePudding user response:

Try the following approach to recursively flatmap the child streams:

Stream<ParentItem> flatMapChildren(ParentItem item ) {
    return Stream.concat( //flatMap replaces the item in the stream so we need concat() to keep it
         Stream.of(item), //create a 1-element stream for the item that gets replaced
         item.childItem.stream() //create a stream for the children 
                       .flatMap(YourClass::flatMapChildren) //recursively add their children
    );
}

Then use that on your top level stream:

List<ParentItem> topLevel = ....;
Stream<String> streamOfAllNames = 
  topLevel.flatMap(YourClass::flatMapChildren)
          .map(ParentItem::getName());

Note: the implementation doesn't contain null checks etc. for simplicity reasons. Add those in your actual code.

CodePudding user response:

    public static void main(String[] args) {
        ParentItem grandpa = new ParentItem();
        
        List<String> listOfItemNames = Stream.of(grandpa)
                .flatMap(Main::loadChildRecursively)
                .map(ParentItem::getItemName)
                .collect(Collectors.toList());
        listOfItemNames.forEach(System.out::println);
    }

    private static Stream<ParentItem> loadChildRecursively(ParentItem parent) {
        if (parent.getChildItem() != null && parent.getChildItem().size() > 0) {
            return Stream.concat(parent.getChildItem().stream().flatMap(Main::loadChildRecursively), Stream.of(parent));
        } else {
            return Stream.of(parent);
        }
    }

An important thing to keep in mind is, when calling the recursive function always add / include your parent object, otherwise you'll end up only having the lowest level of children and no parents.

  • Related