下面就为大家详细讲解如何使用Java8实现菜单树形数据的完整攻略。
1. 梳理数据结构
首先,我们要明确这个菜单树形数据的结构。一般而言,树形结构的数据是由父子关系构成的,因此,我们可以通过用一个节点对象来表示一个特定的菜单项,并在节点对象中维护包括菜单项的标识、菜单项的名称、菜单项的父标识等关键字段。以此来构建菜单树的数据结构。
具体而言,节点对象一般应包括以下字段:
- id:标识节点的唯一标识
- name:节点的名称
- parentId:节点的父级标识,可为空
2. 准备数据集合
准备好节点对象的定义之后,我们需要定义一个包含所有菜单项的集合进行存储,我们可以使用代码定义如下:
List<Node> allNodes = new ArrayList<Node>();
Node是我们定义的节点对象。下面是一个示例的数据集合:
Node node1 = new Node(1, "Dashboard", null);
Node node2 = new Node(2, "Statistics", null);
Node node11 = new Node(11, "Analytics", 1);
Node node12 = new Node(12, "Finance", 1);
Node node21 = new Node(21, "Users", 2);
Node node22 = new Node(22, "Orders", 2);
Node node111 = new Node(111, "Sales Report", 11);
Node node112 = new Node(112, "Traffic Report", 11);
Node node121 = new Node(121, "Balance Sheet", 12);
Node node122 = new Node(122, "Income Statement", 12);
allNode.add(node1);
allNode.add(node2);
allNode.add(node11);
allNode.add(node12);
allNode.add(node21);
allNode.add(node22);
allNode.add(node111);
allNode.add(node112);
allNode.add(node121);
allNode.add(node122);
如上所示,我们定义了10个节点对象,其中菜单项之间的父子关系已经构成。
3. 利用Java8实现树形数据
在使用Java8之前,我们通常需要先实现一个这样的递归算法来将数据集合转换为树形数据。Java8提供了强大的Stream API,通过它,我们可以实现一种更加简洁的方法来转换数据集合。
代码示例:
private List<Node> buildTree(List<Node> allNodes) {
// 获取所有菜单项的map
Map<Integer, Node> allNodesMap = allNodes.stream()
.collect(Collectors.toMap(Node::getId, Function.identity()));
// 构建菜单项的根节点集合
List<Node> rootNodes = allNodes.stream()
.filter(node -> node.getParentId() == null)
.collect(Collectors.toList());
// 遍历所有的节点,将其构建到相应的父级节点下
allNodes.forEach(node -> {
if (node.getParentId() != null) {
Node parentNode = allNodesMap.get(node.getParentId());
parentNode.addChild(node); // 将节点添加到父级节点下的子节点集合
}
});
return rootNodes;
}
如上所示,我们首先通过stream()
方法获取数据集合的Stream流。然后通过collect()
操作将Stream流转换为一个Map,以菜单项的Id为Key,菜单项的对象为Value。这样,在后续的程序处理中,就可以方便地快速查找某个菜单项。
接下来,我们通过Stream API中提供的过滤功能,过滤出数据集合中的根节点,本例中根节点的规定是:如果该节点的parentId为null,则代表其为一个根节点。
之后,我们通过Stream API中的遍历和操作,将每个菜单项添加到其对应的父节点中去。最后,我们返回生成的菜单树形结构的根节点集合。
4. 示例演示
代码示例:
List<Node> result = buildTree(allNodes);
// 输出所有根节点下的子孙菜单项
result.forEach(node -> {
printTree(node, 0);
});
/**
* 遍历输出树形菜单
* @param node 节点对象
* @param level 节点级别
*/
private void printTree(Node node, int level) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < level; i++) {
builder.append(" ");
}
builder.append(node.getName());
System.out.println(builder.toString());
node.getChildren().forEach(subNode -> printTree(subNode, level + 1));
}
结果输出:
Dashboard
Analytics
Sales Report
Traffic Report
Finance
Balance Sheet
Income Statement
Statistics
Users
Orders
在如上的示例中,我们首先调用了buildTree()
方法,将所有的节点对象生成为树形结构的菜单项。接着,我们遍历输出所有的树形菜单项,输出结果即为整棵菜单树形结构。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:教你如何使用Java8实现菜单树形数据 - Python技术站