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.
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.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.