- 39
- 0
原代码:
private static JSONArray produceTree(List<Resource> resources,boolean needPermission){
JSONArray tree = new JSONArray();
if(resources!=null&&resources.size()>Number.ZERO) {//递归退出条件判断
for (Resource resource : resources) {
List<Resource> resourceList=resourceService.queryChildTreeByPid(resource.getId());//根据父id查询子资源列表
JSONArray children = produceTree(resourceList,needPermission,staffName,roleId);//递归,一直向下查找
JSONObject node=TreeUtil.spellTree(resource);//转换为具体的树形式
if(children!=null&&children.size()>Number.ZERO){
node.put("children",children);
}else if(needPermission){//需要该资源下对应的权限信息(最后一级,判断下面有没有权限关系)
node=toPermission(resource.getId(),node,staffName);
}
tree.add(node);
}
}
return tree;
}
Resource结构如下:
@Data
public class Resource {
private Integer id;//资源id
private String resourceName;//资源名称
private String url;//资源地址 可能无用
private String icon;//资源图标
private String clue;// 树形结构横向线索
private Integer distance; // 到根节点的距离 纵向线索
private Integer parentId;// 父资源id
private String description; //资源描述
private Date createtime;//创建时间
private Integer state;// 0未删除 1已删除
List<Resource> children;
}
现在想用java8 Stream流重写这段代码,大概是这样:
private static List<Resource> recursive(List<Resource> resources){
return resources.stream()
.map(Resource::getId)//第一步转换为id
.map(parentId->resourceService.queryChildTreeByPid(parentId))//第二步查找id下对应的资源(id相当于parentId使用)
.map(child->Optional.ofNullable(child).filter(obj -> true).ifPresent(isExists->recursive(isExists)))//第三步 如果childrenList不为null,递归此方法
.toArray(childrenL->reReousce.setChildren());//第四步 将得到的List<Resource> 收集到上一个resource的children中 , resource.setChildren(childrenList)
}
第三步以后 编译出错
设想一下 第三步应该用toArray方法收集子资源 然后第四步将收集到的子资源放进对应的父资源resource中 请问如何实现呢
--------------感谢imanguo大佬的指点 还有某me姓大佬的指点 分享下我的树形结构生产源码-------
--------------Any library suggestions/code samples/guidance would be greatly appreciated...--------------
private static ResourceService resourceService;
private static PermissionService permissionService;
@Autowired
public TreeUtil(ResourceService resourceService,PermissionService permissionService){
this.resourceService=resourceService;
this.permissionService=permissionService;
}
/**
* @Author: zms
* @Description: 生成菜单树结构
*
* clue是线索 例如 1-2-3 代表 根节点是1 1下面有2节点 2下面有3节点
* 根据收集根节点id 作为线索 可以去除持久化数据里面重复的资源
* 例如 同时有了 1节点 2节点 因为1是2的父节点 那么有了1就不需要2的存在了 有父节点就拥有其所有子节点
*
* @Date: Create on 2018/11/12 14:59
*/
public static List<Resource> produceTree(List<Resource> resources,boolean needPermission){
Map<Boolean,List<Resource>> listMap=partitionResource(resources);
List<Resource> nodeTree=listMap.get(true);//根节点资源树
List<Resource> duplicateChildTree=listMap.get(false);//非根节点
String clue=nodeTree.stream().map(Resource::getId).map(String::valueOf).collect(joining("-","","-"));//根节点线索
List<Resource> childTree=duplicateChildTree.stream().filter(resource -> !clue.contains(resource.getClue())).collect(toList());//去除重复资源
nodeTree.addAll(childTree);//合并所有
List<Resource> downTree=TreeUtil.recursiveDown(nodeTree,needPermission);//向下递归查找子节点
List<Resource> upTree=TreeUtil.recursiveUp(downTree);//向上递归查找父节点
return merge(upTree);
}
/**
* @Author: zms
* @Description: 新递归生成树方法 上至下
*
* 5 ---
* 2 --- 6 ---
* 1--- 3 --- 7 ---
* 4 --- 8 ---
* 9 ---
*
* 以1开始查找到2,3,4 然后2,3,4再次递归 2(5,6) 3(7) 4(8,9) 括号内是对应的children
* 为什么引入ResourceGroup? 将resource和ChildrenResource 向上抽象一层
* Resource中含有其他属性 ResourceGroup仅仅表示父子节点的关系 可以不使用 看个人习惯
* @Date: Create on 2018/11/8 11:30
*/
public static List<Resource> recursiveDown(List<Resource> resources, boolean needPermission){
return resources
.parallelStream()
.map(resource -> TreeUtil.toResourceGroup(resource,needPermission))
.peek(ResourceGroup::autoSet)
.map(ResourceGroup::getParent)
.collect(Collectors.toList());
}
/**
* @Author: zms
* @Description: 转换成resouceGroup收集
* @Date: Create on 2018/11/8 11:30
*/
private static ResourceGroup toResourceGroup(Resource resource, boolean needPermission) {
ResourceGroup resourceGroup=new ResourceGroup();
resourceGroup.setParent(resource);
List<Resource> children = findChildren(resource.getId(),needPermission);
if(Objects.equals(0,children.size())&&needPermission){
List<Permission> permissions=permissionService.getPermissionByResourceId(resource.getId());
resourceGroup.setPermissions(permissions);
return resourceGroup;
}
resourceGroup.setChildren(children);
return resourceGroup;
}
/**
* @Author: zms
* @Description: 获取父节点对应的子资源
* @Date: Create on 2018/11/8 11:30
*/
private static List<Resource> findChildren(Integer parentId,boolean needPermission){
List<Resource> chidren=resourceService.queryChildTreeByPid(parentId);
recursiveDown(chidren,needPermission);
return chidren;
}
/**
* @Author: zms
* @Description: 新递归生成树方法 下至上
* @Date: Create on 2018/11/8 18:32
*/
private static List<Resource> recursiveUp(List<Resource> resources){
return resources.stream()
.map(TreeUtil::toResource)
.map(ResourceGroup::getParent)
.collect(Collectors.toList());
}
/**
*@Author: zms
*@Description: 递归查找父节点
*@Date: Create On 2018/11/10 14:33
*/
private static ResourceGroup toResource(Resource resource){
ResourceGroup resourceGroup=new ResourceGroup();
Resource parent=findParent(resource);
resourceGroup.setParent(parent);
return resourceGroup;
}
/**
* @Author: zms
* @Description: 获取收集好的子资源的父节点
* @Date: Create on 2018/11/8 18:37
*/
private static Resource findParent(Resource resource){
if(Objects.equals(0,resource.getParentId())){
return resource;
}
Resource parent=resourceService.getResourceById(resource.getParentId());
List<Resource> children=new ArrayList<>();
children.add(resource);
parent.setChildren(children);
return recursiveUp(Collections.singletonList(parent)).stream().filter(Objects::nonNull).findFirst().orElse(resource);
}
/**
* @Author: zms
* @Description:
*
* 业务背景: 假设id为1的资源节点下有 2,3,4 三个子资源 可能某个角色只有 2,3的资源树
* 2 -->1
* dulipcate
* 3 -->1
* 这时需要把2 3 合并到 1 下
* @Date: Create on 2018/11/12 11:44
*/
private static List<Resource> merge(List<Resource> duplicateTree){
return duplicateTree
.stream()
.collect(toMap(Resource::getId, Function.identity(),TreeUtil::mergeChildResource))
.entrySet()
.stream()
.map(Map.Entry::getValue)
.collect(Collectors.toList());
}
/**
* @Author: zms
* @Description:
*
* id:1 id:1 id:1
* children:[ children:[ children:[
* { { {
* id=2 id=3 合并为 id=2
* } } },
* ] ] {
* id=3
* }
*
* @Date: Create on 2018/11/12 12:00
*/
private static Resource mergeChildResource(Resource resource1,Resource resource2){
resource1.getChildren().add(resource2.getChildren().get(0));
return resource1;
}
/**
* @Author: zms
* @Description: 根节点与不是根节点的resource分组
* @Date: Create on 2018/11/12 15:01
*/
private static Map<Boolean,List<Resource>> partitionResource(List<Resource> resources){
return resources.stream().collect(partitioningBy(resource-> Objects.equals(0,resource.getParentId())));
}
/**
* @Author: zms
* @Description: 去重方法
* @Date: Create on 2018/8/10 10:13
*/
public static String removeDuplicateString(String str){
return Stream.of(str.split(",")).distinct().collect(Collectors.joining(","));
} - 共 0 条
- 全部回答
-
我願與孤獨長廂廝守っ 普通会员 1楼
在Java 8中,我们可以使用Stream API来简化递归代码。以下是一个使用Stream API重构递归代码的例子:
```java import java.util.List; import java.util.stream.Collectors;
public class Main { public static void main(String[] args) { List
numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); List doubledNumbers = numbers.stream() .map(n -> n * 2) .collect(Collectors.toList()); System.out.println(doubledNumbers); // [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] } } ``` 在这个例子中,我们首先创建了一个包含1到10的列表。然后,我们使用Stream API的map方法来将列表中的每个元素都乘以2。最后,我们使用collect方法将结果收集到一个新的列表中。这个新的列表就是我们原始列表的加倍版本。
这种方法不仅可以简化代码,而且还可以避免在递归过程中出现大量的重复计算。
- 扫一扫访问手机版
回答动态

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器更新之后。服务器里面有部分玩家要重新创建角色是怎么回事啊?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题函数计算不同地域的是不能用内网吧?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题ARMS可以创建多个应用嘛?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题在ARMS如何申请加入公测呀?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题前端小程序接入这个arms具体是如何接入监控的,这个init方法在哪里进行添加?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器刚到期,是不是就不能再导出存档了呢?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器的游戏版本不兼容 尝试更新怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器服务器升级以后 就链接不上了,怎么办?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器转移以后服务器进不去了,怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器修改参数后游戏进入不了,是什么情况?预计能赚取 0积分收益
- 回到顶部
- 回到顶部
