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.