@
aguesuka 是的,可以改一点. 在你的基础上改了下,去掉了 parent. 传了个 parentId 和 ID 的判断相等的 Function. 对泛型类的比较该怎么实现不懂(怎么取参数,怎么判断大小) , 还有就是 Node::new 是什么意思, 调用 Node 的默认构造方法吗? 还是非默认的 Node(E data)?
下面这个是自己改了老半天的, 可能还是有错误, 请路过的谨慎使用... (compare 是判断是否和 pid 的值相等)
public static <E,ID> List<Node<E>> buildTree(Collection<E> elements, Function<E,ID> getID, Function<E,ID> getParentID,
ID pid, Function<E,Boolean> compare){
Map<ID,Node<E>> idNodeMap =
elements.stream().collect(Collectors.toMap(getID,Node::new));
//传进来的集合可能没有包含父类 /最顶级父类
Node<E> root = null;
//返回的列表
List<Node<E>> nodes = new ArrayList<>();
for (E element : elements){
ID selfId = getID.apply(element);
ID parentId = getParentID.apply(element);
Node<E> selfNode = idNodeMap.get(selfId);
//如果这个集合里 有元素有对应的父节点
if (idNodeMap.containsKey(parentId)){
Node<E> parentNode = idNodeMap.get(parentId);
// selfNode.setParent(parentNode); //取消设置父节点,不然看起来很庞大
parentNode.getChildren().add(selfNode);
//如果设置了父节点 pid,而且该节点的父节点也是设置的值 pid
if (pid!=null &&compare.apply(element) && !nodes.contains(selfNode)){
nodes.add(selfNode);
}
}else {
root = selfNode;
//如果设置了父节点 pid,而且该节点的父节点也是设置的值 pid
if (pid!=null &&compare.apply(element) && !nodes.contains(selfNode)){
nodes.add(root);
}
}
}
return nodes;
}
public class Node<E> {
E data;
Set<Node<E>> children;
Node<E> parent;
public Node(E data) {
this.data = data;
children = new HashSet<>();
}
public E getData() {
return data;
}
public void setData(E data) {
this.data = data;
}
public Set<Node<E>> getChildren() {
return children;
}
public void setChildren(Set<Node<E>> children) {
this.children = children;
}
public Node<E> getParent() {
return parent;
}
public void setParent(Node<E> parent) {
this.parent = parent;
}
}
具体调用
List<MenuVO> menuVOList =... 从数据库查出来的结果列表
// 去父节点 pid 为 2 的, 获取该菜单下所有的栏目,
Collection<Node<MenuVO>> nodes = buildTree(menuVOList,e->e.getId(),e->e.getPid(),2,e->e.getPid().intValue() ==2 );