Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to construct a Tree data model using Java 8 Streams

I am investigating Java 8 streams.

I am currently stuck attempting to construct a classic tree structure by streaming a file where each record describes a Parent Child relationship.

I would like my solution to be able to construct a Tree from input data records that resemble the following examples:-

Parent A - Child B
Parent A - Child C
Parent A - Child D
Parent A - Child E
Parent B - Child F
Parent B - Child G
Parent C - Child H
Parent D - Child I
Parent G - Child J

I would like to either construct a LinkedHashMap<String, List<String>>

e.g. end up with

A - B, C, D, E
B - F, G
C - H
D - I
G - J

The closest I get fails with duplicate key

Map<String, List<String>> map = stream.sorted().map(line -> line.split("-")).flatMap(line -> Arrays.stream(line)).collect(Collectors.toMap(Function.identity(), Arrays::asList));

Or using the following Node value object

public class Node {

    private final String name;
    private Node parent;
    private List<Node> children = new LinkedList<>();

}

Construct all tree nodes and with fully populated children node Lists direct from stream my input file.

like image 882
Hector Avatar asked Apr 14 '26 20:04

Hector


1 Answers

This is a job for groupingBy collector:

import static java.util.stream.Collectors.*;

Pattern ptrn = Pattern.compile("Parent (.*) - Child (.*)");

Map<String, List<String>> map = data.stream()
        .sorted()
        .map(ptrn::matcher)
        .filter(Matcher::find)
        .collect(groupingBy(
                m -> m.group(1), 
                LinkedHashMap::new ,
                mapping(m -> m.group(2), toList())
        ));
like image 141
Misha Avatar answered Apr 16 '26 12:04

Misha



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!