hutool(枚举工具-EnumUtil与树结构工具-TreeUtil)

本文介绍了枚举(enum)的基本概念及其在Java中的应用,并详细解释了如何使用EnumUtil工具类操作枚举类型。此外,还探讨了一种灵活的树状结构实现方法,该方法可根据配置文件定义节点间的关系,并提供了自定义字段名的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

介绍
枚举(enum)算一种“语法糖”,是指一个经过排序的、被打包成一个单一实体的项列表。一个枚举的实例可以使用枚举项列表中任意单一项的值。枚举在各个语言当中都有着广泛的应用,通常用来表示诸如颜色、方式、类别、状态等等数目有限、形式离散、表达又极为明确的量。Java从JDK5开始,引入了对枚举的支持。

EnumUtil 用于对未知枚举类型进行操作。

方法
首先我们定义一个枚举对象:

//定义枚举
public enum TestEnum{
    TEST1("type1"), TEST2("type2"), TEST3("type3");
    
    private TestEnum(String type) {
        this.type = type;
    }
    
    private String type;
    
    public String getType() {
        return this.type;
    }
}

getNames
获取枚举类中所有枚举对象的name列表。栗子:

//定义枚举
public enum TestEnum {
    TEST1, TEST2, TEST3;
}
List<String> names = EnumUtil.getNames(TestEnum.class);
//结果:[TEST1, TEST2, TEST3]

getFieldValues
获得枚举类中各枚举对象下指定字段的值。栗子:

List<Object> types = EnumUtil.getFieldValues(TestEnum.class, "type");
//结果:[type1, type2, type3]

getEnumMap
获取枚举字符串值和枚举对象的Map对应,使用LinkedHashMap保证有序,结果中键为枚举名,值为枚举对象。栗子:

Map<String,TestEnum> enumMap = EnumUtil.getEnumMap(TestEnum.class);
enumMap.get("TEST1") // 结果为:TestEnum.TEST1

getNameFieldMap
获得枚举名对应指定字段值的Map,键为枚举名,值为字段值。栗子:

Map<String, Object> enumMap = EnumUtil.getNameFieldMap(TestEnum.class, "type");
enumMap.get("TEST1") // 结果为:type1

考虑到菜单等需求的普遍性,有用户提交了一个扩展性极好的树状结构实现。这种树状结构可以根据配置文件灵活的定义节点之间的关系,也能很好的兼容关系数据库中数据。实现

关系型数据库数据 <-> Tree <-> JSON
树状结构中最大的问题就是关系问题,在数据库中,每条数据通过某个字段关联自己的父节点,每个业务中这个字段的名字都不同,如何解决这个问题呢?

PR的提供者提供了一种解决思路:自定义字段名,节点不再是一个bean,而是一个map,实现灵活的字段名定义。

使用
定义结构
我们假设要构建一个菜单,可以实现系统管理和店铺管理,菜单的样子如下:

系统管理
    |- 用户管理
    |- 添加用户

店铺管理
    |- 商品管理
    |- 添加商品

那这种结构如何保存在数据库中呢?一般是这样的:

id	parentId	name	weight
1	0	系统管理	5
11	1	用户管理	10
111	1	用户添加	11
2	0	店铺管理	5
21	2	商品管理	10
221	2	添加添加	11

我们看到,每条数据根据parentId相互关联并表示层级关系,parentId在这里也叫外键。

构建Tree

// 构建node列表
List<TreeNode<String>> nodeList = CollUtil.newArrayList();

nodeList.add(new TreeNode<>("1", "0", "系统管理", 5));
nodeList.add(new TreeNode<>("11", "1", "用户管理", 222222));
nodeList.add(new TreeNode<>("111", "11", "用户添加", 0));
nodeList.add(new TreeNode<>("2", "0", "店铺管理", 1));
nodeList.add(new TreeNode<>("21", "2", "商品管理", 44));
nodeList.add(new TreeNode<>("221", "2", "商品管理2", 2));

TreeNode表示一个抽象的节点,也表示数据库中一行数据。 如果有其它数据,可以调用setExtra添加扩展字段。

// 0表示最顶层的id是0
List<Tree> treeList = TreeUtil.build(nodeList, “0”);
因为两个Tree是平级的,再没有上层节点,因此为List。

自定义字段名

//配置
TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
// 自定义属性名 都要默认值的
treeNodeConfig.setWeightKey("order");
treeNodeConfig.setIdKey("rid");
// 最大递归深度
treeNodeConfig.setDeep(3);
//转换器
List<Tree<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());
        });

通过TreeNodeConfig我们可以自定义节点的名称、关系节点id名称,这样就可以和不同的数据库做对应。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值