增加LambdaTreeNodeConfig类型,使用Lambda语法进行树节点字段名称自定义,避免代码中对字段名称硬编码

This commit is contained in:
Earlman 2024-08-01 15:20:01 +08:00
parent 68e0186ca7
commit 96db994c87
2 changed files with 213 additions and 24 deletions

View File

@ -0,0 +1,110 @@
package org.dromara.hutool.core.tree;
import org.dromara.hutool.core.func.LambdaUtil;
import org.dromara.hutool.core.func.SerFunction;
import java.util.List;
import java.util.Objects;
/**
* 树配置属性相关使用Lambda语法
* 避免对字段名称硬编码
*
* @author Earlman
*/
public class LambdaTreeNodeConfig<R, T> extends TreeNodeConfig {
private SerFunction<R, T> idKeyFun;
private SerFunction<R, T> parentIdKeyFun;
private SerFunction<R, Comparable<?>> weightKeyFun;
private SerFunction<R, CharSequence> nameKeyFun;
private SerFunction<R, List<R>> childrenKeyFun;
public SerFunction<R, T> getIdKeyFun() {
return idKeyFun;
}
public void setIdKeyFun(SerFunction<R, T> idKeyFun) {
this.idKeyFun = idKeyFun;
}
public SerFunction<R, T> getParentIdKeyFun() {
return parentIdKeyFun;
}
public void setParentIdKeyFun(SerFunction<R, T> parentIdKeyFun) {
this.parentIdKeyFun = parentIdKeyFun;
}
public SerFunction<R, Comparable<?>> getWeightKeyFun() {
return weightKeyFun;
}
public void setWeightKeyFun(SerFunction<R, Comparable<?>> weightKeyFun) {
this.weightKeyFun = weightKeyFun;
}
public SerFunction<R, CharSequence> getNameKeyFun() {
return nameKeyFun;
}
public void setNameKeyFun(SerFunction<R, CharSequence> nameKeyFun) {
this.nameKeyFun = nameKeyFun;
}
public SerFunction<R, List<R>> getChildrenKeyFun() {
return childrenKeyFun;
}
public void setChildrenKeyFun(SerFunction<R, List<R>> childrenKeyFun) {
this.childrenKeyFun = childrenKeyFun;
}
@Override
public String getIdKey() {
SerFunction<?, ?> serFunction = getIdKeyFun();
if (Objects.isNull(serFunction)) {
return super.getIdKey();
}
return LambdaUtil.getFieldName(serFunction);
}
@Override
public String getParentIdKey() {
SerFunction<?, ?> serFunction = getParentIdKeyFun();
if (Objects.isNull(serFunction)) {
return super.getParentIdKey();
}
return LambdaUtil.getFieldName(serFunction);
}
@Override
public String getWeightKey() {
SerFunction<?, ?> serFunction = getWeightKeyFun();
if (Objects.isNull(serFunction)) {
return super.getWeightKey();
}
return LambdaUtil.getFieldName(serFunction);
}
@Override
public String getNameKey() {
SerFunction<?, ?> serFunction = getNameKeyFun();
if (Objects.isNull(serFunction)) {
return super.getNameKey();
}
return LambdaUtil.getFieldName(serFunction);
}
@Override
public String getChildrenKey() {
SerFunction<?, ?> serFunction = getChildrenKeyFun();
if (Objects.isNull(serFunction)) {
return super.getChildrenKey();
}
return LambdaUtil.getFieldName(serFunction);
}
}

View File

@ -14,6 +14,7 @@ package org.dromara.hutool.core.tree;
import org.dromara.hutool.core.collection.ListUtil;
import org.dromara.hutool.core.lang.Console;
import org.dromara.hutool.core.tree.parser.DefaultNodeParser;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@ -59,88 +60,166 @@ public class TreeTest {
@Test
public void treeTest() {
//配置
// 配置
final TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
// 自定义属性名 都要默认值的
treeNodeConfig.setWeightKey("order");
treeNodeConfig.setIdKey("rid");
treeNodeConfig.setDeep(2);
//转换器
// 转换器
final List<MapTree<String>> treeNodes = TreeUtil.build(nodeList, "0", treeNodeConfig,
(treeNode, tree) -> {
tree.setId(treeNode.getId());
tree.setParentId(treeNode.getParentId());
tree.setWeight(treeNode.getWeight());
tree.setName(treeNode.getName());
// 扩展属性 ...
tree.putExtra("extraField", 666);
tree.putExtra("other", new Object());
});
(treeNode, tree) -> {
tree.setId(treeNode.getId());
tree.setParentId(treeNode.getParentId());
tree.setWeight(treeNode.getWeight());
tree.setName(treeNode.getName());
// 扩展属性 ...
tree.putExtra("extraField", 666);
tree.putExtra("other", new Object());
});
Assertions.assertEquals(treeNodes.size(), 2);
}
@Test
public void walkTest(){
public void walkTest() {
final List<String> ids = new ArrayList<>();
final MapTree<String> tree = TreeUtil.buildSingle(nodeList, "0");
tree.walk((tr)-> ids.add(tr.getId()));
tree.walk((tr) -> ids.add(tr.getId()));
Assertions.assertEquals(7, ids.size());
}
@Test
public void walkBroadFirstTest(){
public void walkBroadFirstTest() {
final List<String> ids = new ArrayList<>();
final MapTree<String> tree = TreeUtil.buildSingle(nodeList, "0");
Console.log(tree);
tree.walk((tr)-> ids.add(tr.getId()), true);
tree.walk((tr) -> ids.add(tr.getId()), true);
Assertions.assertEquals(7, ids.size());
}
@Test
public void cloneTreeTest(){
public void cloneTreeTest() {
final MapTree<String> tree = TreeUtil.buildSingle(nodeList, "0");
final MapTree<String> cloneTree = tree.cloneTree();
final List<String> ids = new ArrayList<>();
cloneTree.walk((tr)-> ids.add(tr.getId()));
cloneTree.walk((tr) -> ids.add(tr.getId()));
Assertions.assertEquals(7, ids.size());
}
@Test
public void filterTest(){
public void filterTest() {
// 经过过滤丢掉"用户添加"节点
final MapTree<String> tree = TreeUtil.buildSingle(nodeList, "0");
tree.filter((t)->{
tree.filter((t) -> {
final CharSequence name = t.getName();
return null != name && name.toString().contains("店铺");
});
final List<String> ids = new ArrayList<>();
tree.walk((tr)-> ids.add(tr.getId()));
tree.walk((tr) -> ids.add(tr.getId()));
Assertions.assertEquals(4, ids.size());
}
@Test
public void filterNewTest(){
public void filterNewTest() {
final MapTree<String> tree = TreeUtil.buildSingle(nodeList, "0");
// 经过过滤生成新的树
final MapTree<String> newTree = tree.filterNew((t)->{
final MapTree<String> newTree = tree.filterNew((t) -> {
final CharSequence name = t.getName();
return null != name && name.toString().contains("店铺");
});
final List<String> ids = new ArrayList<>();
newTree.walk((tr)-> ids.add(tr.getId()));
newTree.walk((tr) -> ids.add(tr.getId()));
Assertions.assertEquals(4, ids.size());
final List<String> ids2 = new ArrayList<>();
tree.walk((tr)-> ids2.add(tr.getId()));
tree.walk((tr) -> ids2.add(tr.getId()));
Assertions.assertEquals(7, ids2.size());
}
@Test
public void lambdaConfigTest() {
// 配置自定义属性名 为null则取默认值
LambdaTreeNodeConfig<CustomTreeNode, String> treeNodeConfig = new LambdaTreeNodeConfig<>();
treeNodeConfig.setChildrenKeyFun(CustomTreeNode::getChildrenNodes);
treeNodeConfig.setIdKeyFun(CustomTreeNode::getNodeId);
treeNodeConfig.setNameKeyFun(CustomTreeNode::getLabel);
treeNodeConfig.setParentIdKeyFun(CustomTreeNode::getParentNodeId);
treeNodeConfig.setWeightKeyFun(CustomTreeNode::getSortNo);
// 最大递归深度
treeNodeConfig.setDeep(3);
List<MapTree<String>> treeNodes = TreeUtil.build(nodeList, "0", treeNodeConfig, new DefaultNodeParser<>());
Assertions.assertEquals(treeNodes.size(), 2);
MapTree<String> treeNode1 = treeNodes.get(1);
Assertions.assertNotNull(treeNode1);
Assertions.assertNotNull(treeNode1.getConfig());
Assertions.assertEquals(treeNode1.getChildren().size(), 1);
}
/**
* 自定义工程树节点对象
*
* @author Earlman
*/
private class CustomTreeNode {
// 主键ID
private String nodeId;
// 节点名称
private String label;
// 父级id
private String parentNodeId;
// 排序字段
private Integer sortNo;
// 子节点
private List<CustomTreeNode> childrenNodes;
public String getNodeId() {
return nodeId;
}
public void setNodeId(String nodeId) {
this.nodeId = nodeId;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getParentNodeId() {
return parentNodeId;
}
public void setParentNodeId(String parentNodeId) {
this.parentNodeId = parentNodeId;
}
public Integer getSortNo() {
return sortNo;
}
public void setSortNo(Integer sortNo) {
this.sortNo = sortNo;
}
public List<CustomTreeNode> getChildrenNodes() {
return childrenNodes;
}
public void setChildrenNodes(List<CustomTreeNode> childrenNodes) {
this.childrenNodes = childrenNodes;
}
}
}