如果只想直接看算法的,可以跳到第3个标题;其他几个标题的内容作为背景铺垫,介绍为什么要写这个算法,以及可以解决什么实际问题,解决之后的效果如何。因为如果不联系实际,一些人会认为树之类的数据结构没什么用武之地,太抽象。结合其他几个标题的内容可以帮助理解。
1 问题背景分析
最近在公司做一个知识库分享平台的用户权限的后台功能,大概是这样的:
权限分为很多级,如下图所示:
2 从数据库得到资源树
Resource.java
显然这个resource是没法直接拿来生成树的,需要做一个类
ResourceExt.java
现在需要使用迭代将数据库中查出的Resource组成的List转化为资源树
注意,这里的
注意,这里的List< Resource >并不是某个用户所有权限组成的List,而是他所有资源树的顶点资源组成的List。
取出这个List的方法很简单,就是从数据库中查出他的所有资源,将每个资源的Id放入一个List< Integer >中,遍历,如果哪个Resource的parentid不在这个List中,就把该Resource设置为顶点Resource。
至于如何取到master和slave的公共权限以及master拥有而slave没有的权限呢两个用户的资源id得到的List(因为资源id不会重复,所以可以看做是set),求交集即可。代码如下:
将这两个得到的List取出头结点,然后按照ResourceToExt方法就可以得到需要的若干棵父类资源树List< ResourceExt > masterExtHeads, 和子类资源树List< ResourceExt > slaveExtHeads。 这两个资源树集合是我们在第三部分中要进行处理资源树的集合。
3 判断某个子树是否属于某个父树,如果属于,从父树中删除子树
这里的大概思路是:想要从父资源树中删除子资源树,首先判断子资源树的顶点资源是否是父资源树顶点资源的后代,用一个IteratorHelper的类来记录,如果是,则返回true,并且将该节点的父类资源记录下来,然后进行删除操作。否则,返回false和null。
删除的方法是,首先找到想要删除的资源的父节点,遍历其所有子资源节点,如果id与想要删除的相同,就删除。为什么想要删除子树,删除其头结点就可以为在JVM中,一旦该子树的头结点被删除,之后的所有后代都会因为没有被引用而被当做垃圾回收掉。所以不需要再迭代删除子树中的每一个子节点。
4 前端效果展示
其实前面我省略了很多步骤,只是把最关键的几步放上来了,诸如数据库因为高度不冗余,无法直接查出某个用户全部资源之类的坑我都遇到了。。。。总之就是遇到问题解决问题吧。直接按照上面的代码跑不一定能跑通,因为我删除了一些代码只留下最关键的,给需要的人提供一些解决问题的思路。代码稍作修改应该就可以使用。
我把最终生成的树返回给前端,在页面上就会有如下的显示效果:
当一个用户输入另一个用户的userId想要给他赋权时,前端就会这样显示:

页面中,你并不知道被赋权的人有哪些权限,你只知道你可以赋给他哪些权限,并且是按照权限的层级树状展开的
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!