Building a Tree Structure from a Flat List Using Java 8 Streams

This article demonstrates how to retrieve flat menu data from a database into a List, then use Java 8 Stream operations and recursive methods to assemble a hierarchical tree structure, printing the result as JSON for verification.

Java Captain
Java Captain
Java Captain
Building a Tree Structure from a Flat List Using Java 8 Streams

When a requirement arises to build menus or tree structures, a common database design uses a parentId field; to reduce query load we can fetch all rows at once and process them with Java 8 streams.

/**
 * Menu
 *
 * @author lcry
 * @date 2020/06/01 20:36
 */
@Data
@Builder
public class Menu {
    /** id */
    public Integer id;
    /** name */
    public String name;
    /** parent id, root node is 0 */
    public Integer parentId;
    /** child node list */
    public List<Menu> childList;

    public Menu(Integer id, String name, Integer parentId) {
        this.id = id;
        this.name = name;
        this.parentId = parentId;
    }

    public Menu(Integer id, String name, Integer parentId, List<Menu> childList) {
        this.id = id;
        this.name = name;
        this.parentId = parentId;
        this.childList = childList;
    }
}

The recursive assembly of the tree is performed in a JUnit test that first simulates database retrieval by creating a List of Menu objects, then filters the root nodes (parentId == 0) and assigns each node its children via a recursive helper.

@Test
public void testtree(){
    // Simulate database query
    List<Menu> menus = Arrays.asList(
        new Menu(1,"根节点",0),
        new Menu(2,"子节点1",1),
        new Menu(3,"子节点1.1",2),
        new Menu(4,"子节点1.2",2),
        new Menu(5,"根节点1.3",2),
        new Menu(6,"根节点2",1),
        new Menu(7,"根节点2.1",6),
        new Menu(8,"根节点2.2",6),
        new Menu(9,"根节点2.2.1",7),
        new Menu(10,"根节点2.2.2",7),
        new Menu(11,"根节点3",1),
        new Menu(12,"根节点3.1",11)
    );

    // Get parent nodes
    List<Menu> collect = menus.stream()
        .filter(m -> m.getParentId() == 0)
        .map(m -> {
            m.setChildList(getChildrens(m, menus));
            return m;
        })
        .collect(Collectors.toList());
    System.out.println("-------转json输出结果-------");
    System.out.println(JSON.toJSON(collect));
}

/**
 * Recursively find child nodes
 */
private List<Menu> getChildrens(Menu root, List<Menu> all){
    List<Menu> children = all.stream()
        .filter(m -> Objects.equals(m.getParentId(), root.getId()))
        .map(m -> {
            m.setChildList(getChildrens(m, all));
            return m;
        })
        .collect(Collectors.toList());
    return children;
}

The final JSON output shows the hierarchical menu tree, confirming that the stream‑based approach and recursive method correctly transform a flat list into a nested structure.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaRecursionStreamsTree Structure
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.