©著作权归作者所有:来自51CTO博客作者学Java的小熊的原创作品,请联系作者获取转载授权,否则将追究法律责任
平时大概率我们会构建一些树形结果返回给前端,比如菜单结构、部门列表、文件结构等,我们一般想到的就是利用递归来循环构建;现在,就我个人解决的方法如下:
原始递归利用Java 8 Stream流进行处理(原理还是递归)Stream流升级构建场景构建
public class TreeSelect implements Serializable
{
private Long id;
private String label;
private Long parentId;
private List<TreeSelect> children;
public TreeSelect()
{
}
public TreeSelect(Long id, String label, Long parentId) {
this.id = id;
this.label = label;
this.parentId = parentId;
}
public TreeSelect(TreeSelect treeSelect)
{
this.id = treeSelect.getId();
this.label = treeSelect.getLabel();
this.children = treeSelect.getChildren();
}
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public String getLabel()
{
return label;
}
public void setLabel(String label)
{
this.label = label;
}
public List<TreeSelect> getChildren()
{
return children;
}
public void setChildren(List<TreeSelect> children)
{
this.children = children;
}
}
1、原始递归构建树
public static List<TreeSelect> buildDeptTree(List<TreeSelect> trees)
{
List<TreeSelect> returnList = new ArrayList<TreeSelect>();
List<Long> tempList = new ArrayList<Long>();
for (TreeSelect dept : trees)
{
tempList.add(dept.getId());
}
for (Iterator<TreeSelect> iterator = trees.iterator(); iterator.hasNext();)
{
TreeSelect treeSelect = (TreeSelect) iterator.next();
if (!tempList.contains(treeSelect.getParentId()))
{
recursionFn(trees, treeSelect);
returnList.add(treeSelect);
}
}
if (returnList.isEmpty())
{
returnList = trees;
}
return returnList;
}
private static void recursionFn(List<TreeSelect> list, TreeSelect t)
{
List<TreeSelect> childList = getChildList(list, t);
t.setChildren(childList);
for (TreeSelect tChild : childList)
{
if (hasChild(list, tChild))
{
recursionFn(list, tChild);
}
}
}
private static List<TreeSelect> getChildList(List<TreeSelect> list, TreeSelect t)
{
List<TreeSelect> tlist = new ArrayList<TreeSelect>();
for (TreeSelect n : list) {
if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getId().longValue()) {
tlist.add(n);
}
}
return tlist;
}
private static boolean hasChild(List<TreeSelect> list, TreeSelect t)
{
return getChildList(list, t).size() > 0;
}
2、利用Java 8 Stream流进行处理(原理还是递归)
public static List<TreeSelect> buildDeptTreeByStream(List<TreeSelect> trees){
List<TreeSelect> list = trees.stream().filter(item -> item.getParentId() == 0L).collect(Collectors.toList());
Map<Long, List<TreeSelect>> map = trees.stream().collect(Collectors.groupingBy(TreeSelect::getParentId));
recursionFnTree(list, map);
return list;
}
public static void recursionFnTree(List<TreeSelect> list, Map<Long, List<TreeSelect>> map){
for (TreeSelect treeSelect : list) {
List<TreeSelect> childList = map.get(treeSelect.getId());
treeSelect.setChildren(childList);
if (null != childList && 0 < childList.size()){
recursionFnTree(childList,map);
}
}
}
3、Stream流升级构建
List<TreeSelect> collect = trees.stream().filter(m -> m.getParentId() == 0).map(
(m) -> {
m.setChildren(getChildrenList(m, trees));
return m;
}
).collect(Collectors.toList());
public static List<TreeSelect> getChildrenList(TreeSelect tree, List<TreeSelect> list){
List<TreeSelect> children = list.stream().filter(item -> Objects.equals(item.getParentId(), tree.getId())).map(
(item) -> {
item.setChildren(getChildrenList(item, list));
return item;
}
).collect(Collectors.toList());
return children;
}
PS:个人还是比较倾向用Stream流构建树形结构,节省代码量还通俗易懂!!!Stream在实际开发过程中,运用得体的话,既能节省代码量,还能提高效率,但是复杂的流式处理数据也会让代码看起来不易理解!
赞 收藏 评论 举报相关文章