I have a hierarchical list
like below and I want to convert it to a flat list
.
I have wrote a method called convertToFlatList
If you use Java 8, just add this method to the Member
class:
public Stream<Member> streamAll(){
if(getChildren() == null){
return Stream.of(this);
}
return Stream.concat(Stream.of(this), getChildren().stream().flatMap(Member::streamAll));
}
Alternatively, you can remove the null check if you always initialize children
to an empty list :
public Stream<Member> streamAll(){
return Stream.concat(Stream.of(this), getChildren().stream().flatMap(Member::streamAll));
}
Then to get the flat list:
List<Member> convertedList = memberList.stream()
.flatMap(Member::streamAll)
.collect(Collectors.toList());
If a Member
has children, you correctly add the children to the flattened list, but miss the Member
itself. Just move the addition of the member outside of the else
block add you should be fine:
private static List<Member>
convertToFlatList(List<Member> memberList, List<Member> flatList)
{
for (Member member : memberList)
{
// Always add the member to flatList
flatList.add(memeber);
// If it has children, add them toore
if (member.getChildren() != null)
{
convertToFlatList(member.getChildren(), flatList);
}
}
return flatList;
}
Do this by using java-8 flatMap
and recursion
Change
convertToFlatList
method to take only one argument (i,eList<Member>
)
If getChildren()
is not null
, then do the recursion or else return the current object
private static List<Member> convertToFlatList(List<Member> memberList)
{
return memberList.stream().flatMap(i->{
if(Objects.nonNull(i.getChildren())) {
return Stream.concat(Stream.of(i), convertToFlatList(i.getChildren()).stream());
}
return Stream.of(i);
}).collect(Collectors.toList());
}
Output :
[1, 2, 3, 4, 5, 6, 7]
Actually this is the problem of level/recursive order traversal of a tree. Here is detail of the problem and solutions:
https://en.wikipedia.org/wiki/Tree_traversal
By the way, this is traversal (Depth first-Pre order) of your problem:
static class Member {
List<Member> children = new ArrayList<>();
int id;
boolean visit = false;
}
public List<Member> printList(Member member) {
Stack<Member> stack = new Stack<>();
List<Member> list = new ArrayList<>();
stack.push(member);
while(!stack.isEmpty()) {
Member node = stack.pop();
list.add(node);
for(Member m: node.children) {
stack.push(m);
}
}
return list;
}