您需要了解
-
Java 泛型(上下界,泛型方法)
-
stream 流操作
-
递归
-
函数式接口
运行环境
java version "1.8.0_202"
Show me the code
定义树结构
/**
* @param <T> 类型
* @param <E> 元素
*/
public interface TreeNode<T, E> extends Serializable {
/**
* 获取主键
*
* @return T
*/
T getId();
/**
* 获取子级
*
* @return List<E>
*/
List<E> getChild();
/**
* 子级设值
*
* @param child 子级
*/
void setChild(List<E> child);
/**
* 获取父级主键
*
* @return T
*/
T getParentId();
}
树化
/**
* 树化
*
* @param source 源
* @param <T> 类型
* @return List<E>
*/
public static <T, E extends TreeNode<T, E>> List<E> tree(List<E> source) {
if (Objects.isNull(source) || source.isEmpty()) {
return new ArrayList<>();
}
Map<T, E> map = source.stream().collect(Collectors.toMap(TreeNode::getId, Function.identity()));
Set<E> root = new HashSet<>();
source.forEach(d -> {
T parentId = d.getParentId();
if (map.containsKey(parentId)) {
E parent = map.get(parentId);
List<E> child = parent.getChild();
if (child == null) {
child = new ArrayList<>();
}
child.add(d);
parent.setChild(child);
root.remove(d);
} else {
root.add(d);
}
});
return new ArrayList<>(root);
}
树的搜索
/**
* 搜索树
*
* @param source 源
* @param predicate 搜索条件
* @param <T> 类型
* @return List<E>
*/
public static <T, E extends TreeNode<T, E>> List<E> search(List<E> source, Predicate<E> predicate) {
List<E> target = new ArrayList<>();
source.forEach(o -> {
List<E> child = o.getChild();
if (Objects.nonNull(child) && !child.isEmpty()) {
List<E> searched = search(child, predicate);
if (!searched.isEmpty()) {
o.setChild(searched);
target.add(o);
} else {
if (predicate.test(o)) {
target.add(o);
}
}
} else {
if (predicate.test(o)) {
target.add(o);
}
}
});
return target;
}
使用
/**
* 调用示例
*
* @param args 参数
*/
public static void main(String[] args) {
class BTreeNode implements TreeNode<String, BTreeNode> {
private String bId;
private List<BTreeNode> bChild;
private String bParentId;
private String bName;
public BTreeNode() {
}
public BTreeNode(String bId, String bParentId, String bName) {
this.bId = bId;
this.bParentId = bParentId;
this.bName = bName;
}
public String getBId() {
return bId;
}
public void setBId(String bId) {
this.bId = bId;
}
public List<BTreeNode> getBChild() {
return bChild;
}
public void setBChild(List<BTreeNode> bChild) {
this.bChild = bChild;
}
public String getBParentId() {
return bParentId;
}
public void setBParentId(String bParentId) {
this.bParentId = bParentId;
}
public String getBName() {
return bName;
}
public void setBName(String bName) {
this.bName = bName;
}
@Override
public String getId() {
return getBId();
}
@Override
public List<BTreeNode> getChild() {
return getBChild();
}
@Override
public void setChild(List<BTreeNode> child) {
setBChild(child);
}
@Override
public String getParentId() {
return getBParentId();
}
}
String id = "12";
List<BTreeNode> source = new ArrayList<>();
BTreeNode l11 = new BTreeNode("1", "0", "第一级");
source.add(l11);
BTreeNode l111 = new BTreeNode("11", "1", "第一1级");
source.add(l111);
BTreeNode l112 = new BTreeNode("12", "1", "第一2级");
source.add(l112);
BTreeNode l12 = new BTreeNode("2", "0", "第二级");
source.add(l12);
List<BTreeNode> dataTree = tree(source);
List<BTreeNode> rsp = search(dataTree, bTreeNode -> Objects.equals(id, bTreeNode.getId()));
//自定义处理
System.out.println(rsp);
}
完整代码
package top.mindse.word2pdf;
import java.io.Serializable;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class TreeNodeUtils {
/**
* @param <T> 类型
* @param <E> 元素
*/
public interface TreeNode<T, E> extends Serializable {
/**
* 获取主键
*
* @return T
*/
T getId();
/**
* 获取子级
*
* @return List<E>
*/
List<E> getChild();
/**
* 子级设值
*
* @param child 子级
*/
void setChild(List<E> child);
/**
* 获取父级主键
*
* @return T
*/
T getParentId();
}
/**
* 搜索树
*
* @param source 源
* @param predicate 搜索条件
* @param <T> 类型
* @return List<E>
*/
public static <T, E extends TreeNode<T, E>> List<E> search(List<E> source, Predicate<E> predicate) {
List<E> target = new ArrayList<>();
source.forEach(o -> {
List<E> child = o.getChild();
if (Objects.nonNull(child) && !child.isEmpty()) {
List<E> searched = search(child, predicate);
if (!searched.isEmpty()) {
o.setChild(searched);
target.add(o);
} else {
if (predicate.test(o)) {
target.add(o);
}
}
} else {
if (predicate.test(o)) {
target.add(o);
}
}
});
return target;
}
/**
* 树化
*
* @param source 源
* @param <T> 类型
* @return List<E>
*/
public static <T, E extends TreeNode<T, E>> List<E> tree(List<E> source) {
if (Objects.isNull(source) || source.isEmpty()) {
return new ArrayList<>();
}
Map<T, E> map = source.stream().collect(Collectors.toMap(TreeNode::getId, Function.identity()));
Set<E> root = new HashSet<>();
source.forEach(d -> {
T parentId = d.getParentId();
if (map.containsKey(parentId)) {
E parent = map.get(parentId);
List<E> child = parent.getChild();
if (child == null) {
child = new ArrayList<>();
}
child.add(d);
parent.setChild(child);
root.remove(d);
} else {
root.add(d);
}
});
return new ArrayList<>(root);
}
/**
* 调用示例
*
* @param args 参数
*/
public static void main(String[] args) {
class BTreeNode implements TreeNode<String, BTreeNode> {
private String bId;
private List<BTreeNode> bChild;
private String bParentId;
private String bName;
public BTreeNode() {
}
public BTreeNode(String bId, String bParentId, String bName) {
this.bId = bId;
this.bParentId = bParentId;
this.bName = bName;
}
public String getBId() {
return bId;
}
public void setBId(String bId) {
this.bId = bId;
}
public List<BTreeNode> getBChild() {
return bChild;
}
public void setBChild(List<BTreeNode> bChild) {
this.bChild = bChild;
}
public String getBParentId() {
return bParentId;
}
public void setBParentId(String bParentId) {
this.bParentId = bParentId;
}
public String getBName() {
return bName;
}
public void setBName(String bName) {
this.bName = bName;
}
@Override
public String getId() {
return getBId();
}
@Override
public List<BTreeNode> getChild() {
return getBChild();
}
@Override
public void setChild(List<BTreeNode> child) {
setBChild(child);
}
@Override
public String getParentId() {
return getBParentId();
}
}
String id = "12";
List<BTreeNode> source = new ArrayList<>();
BTreeNode l11 = new BTreeNode("1", "0", "第一级");
source.add(l11);
BTreeNode l111 = new BTreeNode("11", "1", "第一1级");
source.add(l111);
BTreeNode l112 = new BTreeNode("12", "1", "第一2级");
source.add(l112);
BTreeNode l12 = new BTreeNode("2", "0", "第二级");
source.add(l12);
List<BTreeNode> dataTree = tree(source);
List<BTreeNode> rsp = search(dataTree, bTreeNode -> Objects.equals(id, bTreeNode.getId()));
//自定义处理
System.out.println(rsp);
}
}