原创

Java-根据带有分隔符的全路径上下级字符串list生成树状


方式1:
public static void main(String[] args) {
List<String> dbList = Lists.newArrayList("能源A区_动力项目部_输液系统_xxx设备公司", "能源B区_维修厂_zzz设备公司",
"能源A区_动力项目部_三级部门2_yyy设备公司");
List<ProjectGroupMockDbTreeVo.ProjectGroupMockDbTreeListVo> treeFromByStringList = getTreeFromByStringList(dbList);
System.out.println(JSON.toJSONString(treeFromByStringList));

结果:
[{"id":1,"name":"能源A区","parentId":0,"fullName":"能源A区","children":[{"id":2,"name":"动力项目部","parentId":1,"fullName":"能源A区_动力项目部",
"children":[{"id":3,"name":"三级部门2","parentId":2,"fullName":"能源A区_动力项目部_三级部门2","children":[{"id":4,"name":"yyy设备公司","parentId":3,
"fullName":"能源A区_动力项目部_三级部门2_yyy设备公司","children":[]}]},{"id":5,"name":"输液系统","parentId":2,"fullName":"能源A区_动力项目部_输液系统",
"children":[{"id":6,"name":"xxx设备公司","parentId":5,"fullName":"能源A区_动力项目部_输液系统_xxx设备公司","children":[]}]}]}]},{"id":6,"name":"能源B区",
"parentId":0,"fullName":"能源B区","children":[{"id":7,"name":"维修厂","parentId":6,"fullName":"能源B区_维修厂","children":[{"id":8,"name":"zzz设备公司",
"parentId":7,"fullName":"能源B区_维修厂_zzz设备公司","children":[]}]}]}]
}
@Data
public class ProjectGroupMockDbVo {
//节点ID
private Integer id;
//节点名称
private String name;
//节点父节点ID
private Integer parentId;
//拼接包括所有父级节点的名称
private String fullName;
}
@Data
public class ProjectGroupMockDbTreeVo {
private List<ProjectGroupMockDbTreeListVo> list = new ArrayList<>();

@EqualsAndHashCode(callSuper = true)
@Data
//分类树列表
@JSONType(orders = {"id", "name", "parentId", "fullName", "children"})
public static class ProjectGroupMockDbTreeListVo extends ProjectGroupMockDbVo{
// //节点ID
// private Integer id;
// //节点名称
// private String name;
// //节点父节点ID
// private Integer parentId;
// //拼接包括所有父级节点的名称
// private String fullName;
//
private List<ProjectGroupMockDbTreeListVo> children = new ArrayList<>();
}
}
/**
* @param fullNameWithDelimiterList 带分隔符的全路径
*/
private static List<ProjectGroupMockDbTreeVo.ProjectGroupMockDbTreeListVo> getTreeFromByStringList(
    List<String> fullNameWithDelimiterList){
if(CollectionUtils.isEmpty(fullNameWithDelimiterList)){
return CollectionUtil.newArrayList();
}
//这个排序也能关键
fullNameWithDelimiterList.sort(String::compareTo);

Map<String, Integer> allLevelMap = Maps.newHashMap();
List<ProjectGroupMockDbVo> categoryVoList = Lists.newArrayList();//三级部门2的parentId 没有
int id = 1;
for (String dbStr : fullNameWithDelimiterList) {
String[] oneArr = dbStr.split("_");
for (int i = 0; i < oneArr.length; i++) {
if (i == 0) {
if (allLevelMap.get(oneArr[i]) == null) {
ProjectGroupMockDbVo categoryVo = new ProjectGroupMockDbVo();
categoryVo.setId(id);
categoryVo.setParentId(0);//这里必须是0
categoryVo.setName(oneArr[i]);
categoryVo.setFullName(getAllLevelKey(oneArr, i));
categoryVoList.add(categoryVo);
allLevelMap.put(oneArr[i], id);
}
} else {
Integer childId = allLevelMap.get(getAllLevelKey(oneArr, i));//这里最好是多有的节点
if (childId == null) {
Integer parentId = allLevelMap.get(getAllLevelKey(oneArr, i - 1));
ProjectGroupMockDbVo categoryVo = new ProjectGroupMockDbVo();
categoryVo.setId(++id);
categoryVo.setParentId(parentId);
categoryVo.setName(oneArr[i]);
categoryVo.setFullName(getAllLevelKey(oneArr, i));
categoryVoList.add(categoryVo);
allLevelMap.put(getAllLevelKey(oneArr, i), id);// 要存当前的节点
}
}
}
}
// System.out.println(JSON.toJSONString(categoryVoList));
List<ProjectGroupMockDbTreeVo.ProjectGroupMockDbTreeListVo> categoryTreeVoList2s = TreeUtils.listToTree(
JSONArray.parseArray(JSON.toJSONString(categoryVoList)), "id", "parentId", "children").
toJavaList(ProjectGroupMockDbTreeVo.ProjectGroupMockDbTreeListVo.class);
// System.out.println(JSON.toJSONString(categoryTreeVoList2s));
return categoryTreeVoList2s;
}

//返回当前节点到上级节点的key
private static String getAllLevelKey(String[] oneArr, int currentNode) {
StringBuilder key = new StringBuilder();
for (int i = 0; i <= currentNode; i++) {
key.append(oneArr[i]);
key.append("_");
}
return key.substring(0, key.length() - 1);
}
package cn.jiangjiesheng.edu.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
* @author huangzhiqiang
* @date 2021/6/24
*/

public class TreeUtils {
/**
* listToTree
* <p>方法说明<p>
* 将JSONArray数组转为树状结构
* @param arr 需要转化的数据
* @param id 数据唯一的标识键值
* @param pid 父id唯一标识键值
* @param child 子节点键值
* @return JSONArray
*/
public static JSONArray listToTree(JSONArray arr, String id, String pid, String child){
JSONArray r = new JSONArray();
JSONObject hash = new JSONObject();
// 将数组转为Object的形式,key为数组中的id
for(int i=0;i<arr.size();i++){
JSONObject json = (JSONObject) arr.get(i);
hash.put(json.getString(id), json);
}
// 遍历结果集
for(int j=0;j<arr.size();j++){
// 单条记录
JSONObject aVal = (JSONObject) arr.get(j);
// 在hash中取出key为单条记录中pid的值
JSONObject hashVP = (JSONObject) hash.get(aVal.get(pid).toString());
// 如果记 录的pid存在,则说明它有父节点,将她添加到孩子节点的集合中
if(hashVP!=null){
// 检查是否有child属性
if(hashVP.get(child)!=null){
JSONArray ch = (JSONArray) hashVP.get(child);
ch.add(aVal);
hashVP.put(child, ch);
}else{
JSONArray ch = new JSONArray();
ch.add(aVal);
hashVP.put(child, ch);
}
}else{
r.add(aVal);
}
}
return r;
}
}

方式2:(js实现)
var arr = ["能源A区_动力项目部_输液系统_xxx设备公司","能源B区_维修厂_zzz设备公司","能源A区_动力项目部_三级部门2_yyy设备公司"];
var arrpinyin = ["nengyuanaqu_donglixiangmubu_shuyexitong_xxxshebeigongsi",
        "nengyuanbqu_weixiuchang_zzzshebeigongsi","nengyuanaqu_donglixiangmubu_sanjibumen2_yyyshebeigongsi"];
const idNameMap = {}
const idTreeMap = {}

function formatterTree(obj, arrpinyinIndex, sindex){
const arr = arrpinyin[arrpinyinIndex].split('_');
if(arr.length>sindex){
const temArr = arrpinyin[arrpinyinIndex].split('_')
const id = sindex===0?temArr[0]:temArr.splice(0, sindex+1).join('-');
if(!obj[id]){
obj[id] = {};
}
if(sindex<arr.length){
formatterTree(obj[id], arrpinyinIndex, sindex+1)
}
}
}

arrpinyin.forEach((item,index) => {
formatterTree(idTreeMap, index, 0)
item.split('_').forEach((sitem,sindex) => {
const temArr = item.split('_')
const id = sindex===0?temArr[0]:temArr.splice(0, sindex+1).join('-');
idNameMap[id] = sindex===0?arr[index].split('_')[0]:arr[index].split('_').splice(0, sindex+1).join('-');
})
})

const treeData = [];
function formatterTreeData(obj, arr){
Object.keys(obj).forEach(key => {
const nameArr = idNameMap[key].split('-')
arr.push({
id: key,
name: nameArr[nameArr.length-1],
allName:idNameMap[key],
children: []
})
if(obj[key]){
formatterTreeData(obj[key],arr[arr.length-1].children)
}
})
}
formatterTreeData(idTreeMap, treeData)
console.log(JSON.stringify(treeData))
console.log(idNameMap)

正文到此结束
本文目录