Java Stream流实现递归查询树型结构
MySql数据库表结构
模拟数据
查询出所有数据,用父节点递归查询出所有子节点数据
/**
* 封装备注分类集合
*
* @param remarkTypeList 备注分类集合
* @return 递归好的集合
*/
@Override
public List<RemarkType> queryRemarkTypeList(List<RemarkType> remarkTypeList) {
Map<Long, List<RemarkType>> childrenMap = remarkTypeList.stream()
.filter(item -> Objects.equals("0", item.getDisplayStatus()))
.collect(Collectors.groupingBy(RemarkType::getParentId));
return getChildren(0L, childrenMap);
}
/**
* 递归查询子节点
*
* @param parentId 父id
* @param childrenMap 子节点Map
* @return 节点分类列表
*/
private List<RemarkType> getChildren(Long parentId, Map<Long, List<RemarkType>> childrenMap) {
return Optional.ofNullable(childrenMap.get(parentId))
.orElse(Collections.emptyList())
.stream()
.peek(item -> item.setChildren(getChildren(item.getRemarkTypeId(), childrenMap)))
.sorted(Comparator.comparingInt(item -> Optional.ofNullable(item.getSort()).orElse(0)))
.collect(Collectors.toList());
}
查询结果:
{
"msg": "操作成功",
"code": 200,
"data": [
{
"remarkTypeId": 1,
"typeName": "未接通",
"parentId": 0,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": [
{
"remarkTypeId": 4,
"typeName": "关机",
"parentId": 1,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 5,
"typeName": "空号",
"parentId": 1,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 6,
"typeName": "停机",
"parentId": 1,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 7,
"typeName": "通话中",
"parentId": 1,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 8,
"typeName": "无法接通",
"parentId": 1,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 9,
"typeName": "无人接听",
"parentId": 1,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
}
]
},
{
"remarkTypeId": 2,
"typeName": "已接通",
"parentId": 0,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": [
{
"remarkTypeId": 10,
"typeName": "开场白挂机",
"parentId": 2,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": [
{
"remarkTypeId": 21,
"typeName": "开场白挂断",
"parentId": 10,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 22,
"typeName": "用户不说话",
"parentId": 10,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
}
]
},
{
"remarkTypeId": 11,
"typeName": "客户忙",
"parentId": 2,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": [
{
"remarkTypeId": 23,
"typeName": "在忙没空",
"parentId": 11,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
}
]
},
{
"remarkTypeId": 12,
"typeName": "需要屏蔽",
"parentId": 2,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": [
{
"remarkTypeId": 24,
"typeName": "说不要再打了",
"parentId": 12,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
}
]
},
{
"remarkTypeId": 13,
"typeName": "已充值",
"parentId": 2,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": [
{
"remarkTypeId": 25,
"typeName": "套餐转移",
"parentId": 13,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 26,
"typeName": "正在使用",
"parentId": 13,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
}
]
},
{
"remarkTypeId": 14,
"typeName": "已退货",
"parentId": 2,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 15,
"typeName": "有充值意向",
"parentId": 2,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": [
{
"remarkTypeId": 27,
"typeName": "用户承诺近期充值",
"parentId": 15,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 28,
"typeName": "已引导",
"parentId": 15,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
}
]
},
{
"remarkTypeId": 16,
"typeName": "物流正在路上",
"parentId": 2,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": [
{
"remarkTypeId": 29,
"typeName": "还没拿到已引导",
"parentId": 16,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
}
]
},
{
"remarkTypeId": 17,
"typeName": "用户不需要",
"parentId": 2,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": [
{
"remarkTypeId": 30,
"typeName": "骂人",
"parentId": 17,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 31,
"typeName": "准备退货",
"parentId": 17,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 32,
"typeName": "试用不满意",
"parentId": 17,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 33,
"typeName": "价格高",
"parentId": 17,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 34,
"typeName": "说我们骗人",
"parentId": 17,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 35,
"typeName": "在用其他家的",
"parentId": 17,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 36,
"typeName": "设备不在身边",
"parentId": 17,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 37,
"typeName": "不用了不需要",
"parentId": 17,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
}
]
},
{
"remarkTypeId": 18,
"typeName": "用户不知情购买",
"parentId": 2,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": [
{
"remarkTypeId": 38,
"typeName": "非本人购买,已让转告",
"parentId": 18,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 39,
"typeName": "用户说没购买",
"parentId": 18,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
}
]
},
{
"remarkTypeId": 19,
"typeName": "用户犹豫",
"parentId": 2,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": [
{
"remarkTypeId": 40,
"typeName": "赠送免费流量",
"parentId": 19,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 41,
"typeName": "答应减免充值金额",
"parentId": 19,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
}
]
}
]
},
{
"remarkTypeId": 3,
"typeName": "其他",
"parentId": 0,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": [
{
"remarkTypeId": 20,
"typeName": "一退",
"parentId": 3,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": [
{
"remarkTypeId": 42,
"typeName": "物流拦截",
"parentId": 20,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
},
{
"remarkTypeId": 43,
"typeName": "中途退货",
"parentId": 20,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
}
]
},
{
"remarkTypeId": 44,
"typeName": "电商备注",
"parentId": 3,
"displayStatus": "0",
"sort": 0,
"contactWay": "电话",
"children": []
}
]
}
]
}
根据子节点查询所有父节点数据
/**
* 根据子节点查询全部父节点
*
* @param category 备注类型对象
* @return 节点集合
*/
@Override
public List<String> getParent(RemarkType category) {
List<String> types = new ArrayList<>();
//没到顶层节点就一直递归
if (category.getParentId() != 0L) {
RemarkType parentCategory = getById(category.getParentId());
types.addAll(getParent(parentCategory));
}
types.add(category.getTypeName());
return types;
}
查询结果:
{
"msg": "操作成功",
"code": 200,
"data": [
"已接通",
"客户忙",
"在忙没空"
]
}