java List递归排序,传统方式和java8 Stream优化递归,无序的列表按照父级关系进行排序(两种排序类型)
当有一个List列表是无序的,List中的数据有parentid进行关联,通过java排序成两种排序类型:
所用的测试列表最顶级无parentid,若为特殊值,修改下判断方法即可。
第一种排序:按照树结构进行排序
排序前:122,13,121,1,131,12,132...
无序的
[TestSort [id=122, name=三级b, parentid=12], TestSort [id=13, name=二级b, parentid=1], TestSort [id=121, name=三级a, parentid=12], TestSort [id=1, name=一级, parentid=null], TestSort [id=131, name=三级c, parentid=13], TestSort [id=12, name=二级a, parentid=1], TestSort [id=132, name=三级d, parentid=13]]
排序后:1,13,131,132,12,122,121...
按照树结构排序
[TestSort [id=1, name=一级, parentid=null], TestSort [id=13, name=二级b, parentid=1], TestSort [id=131, name=三级c, parentid=13], TestSort [id=132, name=三级d, parentid=13], TestSort [id=12, name=二级a, parentid=1], TestSort [id=122, name=三级b, parentid=12], TestSort [id=121, name=三级a, parentid=12]]
测试实体类:
/**
* <p>部门列表排序测试类<p>
* @version 1.0
* @author li_hao
* @date 2018年4月12日
*/
public class Dept { private String id; //id
private String name; //名称
private String parentid; //父级id public Dept(){
super();
} public Dept(String id, String name, String parentid) {
super();
this.id = id;
this.name = name;
this.parentid = parentid;
} public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getParentid() {
return parentid;
}
public void setParentid(String parentid) {
this.parentid = parentid;
}
@Override
public String toString() {
return "TestSort [id=" + id + ", name=" + name + ", parentid=" + parentid + "]";
}
}
排序代码(第一种排序):
1. 传统方式:
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.apache.commons.lang.StringUtils; /**
* <p>列表排序,按照树结构排序list(顶级无父节点)<p>
* 排序前:122,13,121,1,131,12,132...
* 无序的
* [TestSort [id=122, name=三级b, parentid=12], TestSort [id=13, name=二级b, parentid=1], TestSort [id=121, name=三级a, parentid=12], TestSort [id=1, name=一级, parentid=null], TestSort [id=131, name=三级c, parentid=13], TestSort [id=12, name=二级a, parentid=1], TestSort [id=132, name=三级d, parentid=13]]
*
* 排序后:1,13,131,132,12,122,121...
* 按照树结构排序
* [TestSort [id=1, name=一级, parentid=null], TestSort [id=13, name=二级b, parentid=1], TestSort [id=131, name=三级c, parentid=13], TestSort [id=132, name=三级d, parentid=13], TestSort [id=12, name=二级a, parentid=1], TestSort [id=122, name=三级b, parentid=12], TestSort [id=121, name=三级a, parentid=12]]
* @version 1.0
* @author li_hao
* @date 2018年4月12日
*/
public class DeptSort { private List<Dept> resultList = new ArrayList<>(); //输出列表
private List<Dept> deptList; //输入列表 /**
* 排序
* @param deptList
*/
public DeptSort(List<Dept> deptList){
this.deptList = deptList; for(Dept dept : this.deptList){
if(StringUtils.isBlank(dept.getParentid())){ //当父级为空
resultList.add(dept); //当父级为空时即顶级,首先放入输出列表
findChildren(dept); //查询下级
}
}
} /**
* 查询下级
* @param dept
*/
private void findChildren(Dept dept){
List<Dept> childrenList = new ArrayList<>();
//遍历输入列表,查询下级
for(Dept d : deptList){
if(Objects.equals(dept.getId(), d.getParentid()))
childrenList.add(d);
}
//遍历到最末端,无下级,退出遍历
if(childrenList.isEmpty()){
return;
}
//对下级进行遍历
for(Dept d : childrenList){
resultList.add(d);
findChildren(d);
}
} public List<Dept> getResultList(){
return resultList;
} public static List<Dept> sort(List<Dept> originalList){
return new DeptSort(originalList).getResultList();
} /**
* 测试
* @param args
*/
public static void main(String[] args) {
List<Dept> originalList = new ArrayList<Dept>();
originalList.add(new Dept("122", "三级b", "12"));
originalList.add(new Dept("13", "二级b", "1"));
originalList.add(new Dept("121", "三级a", "12"));
originalList.add(new Dept("1", "一级", null));
originalList.add(new Dept("131", "三级c", "13"));
originalList.add(new Dept("12", "二级a", "1"));
originalList.add(new Dept("132", "三级d", "13")); List<Dept> resultList = DeptSort.sort(originalList);
System.out.println("输入列表:"+ originalList);
System.out.println("输出列表:"+ resultList);
}
}
2. java8 Stream优化递归:
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang.StringUtils; /**
* java8 Stream 优化递归
* <p>列表排序,按照树结构排序list(顶级无父节点)<p>
* 排序前:122,13,121,1,131,12,132...
* 无序的
* [TestSort [id=122, name=三级b, parentid=12], TestSort [id=13, name=二级b, parentid=1], TestSort [id=121, name=三级a, parentid=12], TestSort [id=1, name=一级, parentid=null], TestSort [id=131, name=三级c, parentid=13], TestSort [id=12, name=二级a, parentid=1], TestSort [id=132, name=三级d, parentid=13]]
*
* 排序后:1,13,131,132,12,122,121...
* 按照树结构排序
* [TestSort [id=1, name=一级, parentid=null], TestSort [id=13, name=二级b, parentid=1], TestSort [id=131, name=三级c, parentid=13], TestSort [id=132, name=三级d, parentid=13], TestSort [id=12, name=二级a, parentid=1], TestSort [id=122, name=三级b, parentid=12], TestSort [id=121, name=三级a, parentid=12]]
* @version 1.0
* @author li_hao
* @date 2018年4月12日
*/
public class DeptSortJava8 { private List<Dept> deptList; public DeptSortJava8(List<Dept> deptList) {
this.deptList = deptList;
} public static List<Dept> sort(List<Dept> originalList) {
return new DeptSortJava8(originalList).sort();
} private List<Dept> sort() {
return this.deptList.stream()
.filter(d -> StringUtils.isBlank(d.getParentid()))
.flatMap(d -> Stream.concat(Stream.of(d), findChildren(d)))
.collect(Collectors.toList());
} /**
* 查询下级部门
* @param dept
*/
private Stream<Dept> findChildren(Dept dept) {
return deptList.stream()
.filter(d -> Objects.equals(dept.getId(), d.getParentid()))
.flatMap(d -> Stream.concat(Stream.of(d), findChildren(d)));
} /**
* 测试
* @param args
*/
public static void main(String[] args) {
List<Dept> originalList = new ArrayList<Dept>();
originalList.add(new Dept("122", "三级b", "12"));
originalList.add(new Dept("13", "二级b", "1"));
originalList.add(new Dept("121", "三级a", "12"));
originalList.add(new Dept("1", "一级", null));
originalList.add(new Dept("131", "三级c", "13"));
originalList.add(new Dept("12", "二级a", "1"));
originalList.add(new Dept("132", "三级d", "13")); List<Dept> resultList = DeptSortJava8.sort(originalList);
System.out.println("输入列表:"+ originalList);
System.out.println("输出列表:"+ resultList);
}
}
测试结果:
排序前:
[TestSort [id=122, name=三级b, parentid=12], TestSort [id=13, name=二级b, parentid=1], TestSort [id=121, name=三级a, parentid=12], TestSort [id=1, name=一级, parentid=null], TestSort [id=131, name=三级c, parentid=13], TestSort [id=12, name=二级a, parentid=1], TestSort [id=132, name=三级d, parentid=13]]
排序后:
[TestSort [id=1, name=一级, parentid=null], TestSort [id=13, name=二级b, parentid=1], TestSort [id=131, name=三级c, parentid=13], TestSort [id=132, name=三级d, parentid=13], TestSort [id=12, name=二级a, parentid=1], TestSort [id=122, name=三级b, parentid=12], TestSort [id=121, name=三级a, parentid=12]]
第二种排序:按照层级从上到下进行排序,同级的放一块
排序前:122,13,121,1,131,12,132...
无序的
[TestSort [id=122, name=三级b, parentid=12], TestSort [id=13, name=二级b, parentid=1], TestSort [id=121, name=三级a, parentid=12], TestSort [id=1, name=一级, parentid=null], TestSort [id=131, name=三级c, parentid=13], TestSort [id=12, name=二级a, parentid=1], TestSort [id=132, name=三级d, parentid=13]]
排序后:1,13,12,131,132,122,121...
按照层级排序
[TestSort [id=1, name=一级, parentid=null], TestSort [id=13, name=二级b, parentid=1], TestSort [id=12, name=二级a, parentid=1], TestSort [id=131, name=三级c, parentid=13], TestSort [id=132, name=三级d, parentid=13], TestSort [id=122, name=三级b, parentid=12], TestSort [id=121, name=三级a, parentid=12]]
排序代码(第二种排序):
1. 传统方式:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.TreeMap;
import org.apache.commons.lang.StringUtils; /**
*
* <p>列表排序,按照层级从上到下排序list,同级的放一块(顶级无父节点)<p>
* * 排序前:122,13,121,1,131,12,132...
* 无序的
* [TestSort [id=122, name=三级b, parentid=12], TestSort [id=13, name=二级b, parentid=1], TestSort [id=121, name=三级a, parentid=12], TestSort [id=1, name=一级, parentid=null], TestSort [id=131, name=三级c, parentid=13], TestSort [id=12, name=二级a, parentid=1], TestSort [id=132, name=三级d, parentid=13]]
*
* 排序后:1,13,12,131,132,122,121...
* 按照层级排序
* [TestSort [id=1, name=一级, parentid=null], TestSort [id=13, name=二级b, parentid=1], TestSort [id=12, name=二级a, parentid=1], TestSort [id=131, name=三级c, parentid=13], TestSort [id=132, name=三级d, parentid=13], TestSort [id=122, name=三级b, parentid=12], TestSort [id=121, name=三级a, parentid=12]]
* @version 1.0
* @author li_hao
* @date 2018年4月12日
*/
public class DeptSort2 { private TreeMap<Integer, List<Dept>> treeMap; //定义一个treeMap,key是等级,value是当前的等级对应的所有对象list
private Integer level = 2;
private List<Dept> resultList = new ArrayList(); //输出列表
private List<Dept> deptList; //输入列表 /**
* 排序
* @param deptList
*/
public DeptSort2(List<Dept> deptList) {
this.deptList = deptList; for (Dept dept : this.deptList) {
if (StringUtils.isBlank(dept.getParentid())) { //当父级为空
resultList.add(dept); //当父级为空时即顶级,首先放入输出列表
treeMap = new TreeMap<>();
findChildren(dept); //查询下级
Iterator it = treeMap.keySet().iterator(); //迭代treeMap
while (it.hasNext()) { //检查序列中是否还有元素,如果迭代中还有元素返回true(因为treeMap中放的是2级和2级下面的所有list,所以只需要判断it.hashNext)
resultList.addAll(treeMap.get(it.next())); //把treeMap中所有的list按照层级顺序添加到resultList中
}
}
}
} /**
* 查询下级部门
* 方法进去的时候就记录当前层级数,findchildren方法走完的时候,表示这一层已经没有逻辑了,递归回上一层,所以 this点level减一
* @param dept
*/
private void findChildren(Dept dept) {
Integer level = this.level++; //第一次进来时level值为2,this.level值为3
try {
List<Dept> childrenList = new ArrayList<>();
//遍历输入列表,查询下级
for (Dept d : deptList) {
if (Objects.equals(dept.getId(), d.getParentid()))
childrenList.add(d);
}
//遍历到最末端,无下级,退出遍历
if (childrenList.isEmpty()) {
return;
}
//对下级进行遍历
for (Dept d : childrenList) {
addToMap(level, d); //向treeMap中添加等级和对应dept(第一次执行的level值为2)
findChildren(d); //查询下级,(比如:第一次进来时level值为2,this.level值为3,在进入此方法后,level为3,this.level为4,没查到则跳出,level减一)
}
} finally {
this.level--; //由于再次执行findChildren时,this.level的值+1了,那么在执行完毕后需要finally:this.level--
}
} /**
* 向treeMap中添加等级和对应的List
* @param level
* @param dept
*/
void addToMap(Integer level, Dept dept) {
if (Objects.isNull(treeMap.get(level)))
treeMap.put(level, new ArrayList<Dept>()); //先判断下对应层级在map里有没有,没有就初始化,给个list treeMap.get(level).add(dept); //若treeMap中有等级,则添加dept
} public List<Dept> getResultList() {
return resultList;
} public static List<Dept> sort(List<Dept> originalList) {
return new DeptSort2(originalList).getResultList();
} /**
* 测试
* @param args
*/
public static void main(String[] args) {
List<Dept> originalList = new ArrayList<Dept>();
originalList.add(new Dept("122", "三级b", "12"));
originalList.add(new Dept("13", "二级b", "1"));
originalList.add(new Dept("121", "三级a", "12"));
originalList.add(new Dept("1", "一级", null));
originalList.add(new Dept("131", "三级c", "13"));
originalList.add(new Dept("12", "二级a", "1"));
originalList.add(new Dept("132", "三级d", "13")); List<Dept> resultList = DeptSort2.sort(originalList);
System.out.println("输入列表:"+ originalList);
System.out.println("输出列表:"+ resultList);
}
}
2. java8 Stream优化递归:
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils; /**
* java8 Stream 优化递归
* <p>列表排序,按照层级从上到下排序list,同级的放一块(顶级无父节点)<p>
* * 排序前:122,13,121,1,131,12,132...
* 无序的
* [TestSort [id=122, name=三级b, parentid=12], TestSort [id=13, name=二级b, parentid=1], TestSort [id=121, name=三级a, parentid=12], TestSort [id=1, name=一级, parentid=null], TestSort [id=131, name=三级c, parentid=13], TestSort [id=12, name=二级a, parentid=1], TestSort [id=132, name=三级d, parentid=13]]
*
* 排序后:1,13,12,131,132,122,121...
* 按照层级排序
* [TestSort [id=1, name=一级, parentid=null], TestSort [id=13, name=二级b, parentid=1], TestSort [id=12, name=二级a, parentid=1], TestSort [id=131, name=三级c, parentid=13], TestSort [id=132, name=三级d, parentid=13], TestSort [id=122, name=三级b, parentid=12], TestSort [id=121, name=三级a, parentid=12]]
* @version 1.0
* @author li_hao
* @date 2018年4月12日
*/
public class DeptSortJava82 { private List<Dept> deptList; private List<Dept> resultList = new ArrayList<>(); public DeptSortJava82(List<Dept> deptList) {
this.deptList = deptList;
} public static List<Dept> sort(List<Dept> originalList) {
return new DeptSortJava82(originalList).sort();
} private List<Dept> sort() {
this.deptList.stream()
.filter(d -> StringUtils.isBlank(d.getParentid()))
.forEach(d -> {
resultList.add(d);
findChildren(d);
});
return resultList;
} /**
* 查询下级部门
*
* @param dept
*/
private void findChildren(Dept dept) {
List<Dept> childrenList = deptList.stream()
.filter(d -> Objects.equals(dept.getId(), d.getParentid()))
.collect(Collectors.toList()); if (childrenList.isEmpty())
/* 跳出递归 */
return;
else
childrenList.forEach(d -> {
resultList.add(d);
findChildren(d);
});
} public static void main(String[] args) {
List<Dept> originalList = new ArrayList<Dept>();
originalList.add(new Dept("122", "三级b", "12"));
originalList.add(new Dept("13", "二级b", "1"));
originalList.add(new Dept("121", "三级a", "12"));
originalList.add(new Dept("1", "一级", null));
originalList.add(new Dept("131", "三级c", "13"));
originalList.add(new Dept("12", "二级a", "1"));
originalList.add(new Dept("132", "三级d", "13")); List<Dept> resultList = DeptSortJava82.sort(originalList);
System.out.println("输入列表:"+ originalList);
System.out.println("输出列表:"+ resultList);
}
}
测试结果:
排序前:
[TestSort [id=122, name=三级b, parentid=12], TestSort [id=13, name=二级b, parentid=1], TestSort [id=121, name=三级a, parentid=12], TestSort [id=1, name=一级, parentid=null], TestSort [id=131, name=三级c, parentid=13], TestSort [id=12, name=二级a, parentid=1], TestSort [id=132, name=三级d, parentid=13]]
排序后:
[TestSort [id=1, name=一级, parentid=null], TestSort [id=13, name=二级b, parentid=1], TestSort [id=12, name=二级a, parentid=1], TestSort [id=131, name=三级c, parentid=13], TestSort [id=132, name=三级d, parentid=13], TestSort [id=122, name=三级b, parentid=12], TestSort [id=121, name=三级a, parentid=12]]
源码:https://github.com/piaoliudelaoyaoguai/sortdemo.git
java List递归排序,传统方式和java8 Stream优化递归,无序的列表按照父级关系进行排序(两种排序类型)的更多相关文章
- ch1_6_1求解两种排序方法问题
考拉有n个字符串字符串,任意两个字符串长度都是不同的. 考拉最近学习到有两种字符串的排序方法: 1.根据字符串的字典序排序.例如: "car" < "carr ...
- CList 点击表头排序 (2)两种排序方法中其中一种
上一篇讲解SortItem()方法如何使用,虽然都是抄别人的但是就是想让大家有个大概的了解 CList 点击表头排序 (1)SortItems函数 点击表头排序基本思路都是 1.首先响应HDN_ITE ...
- 列举两种不同类型的Java标识注释,并解释它们之间的区别。
列举两种不同类型的Java标识注释,并解释它们之间的区别.
- CList 点击表头排序 (3)两种排序的第二种
在头两篇中介绍了CListCtrl::SortItems() 方法的使用和其中的一个排序方法,这篇介绍另一种方法 CList 点击表头排序 (1)SortItems函数 CList 点击表头排序 (2 ...
- Java中的两种异常类型及其区别?
Java中的两种异常类型是什么?他们有什么区别? Throwable包含了错误(Error)和异常(Excetion两类) Exception又包含了运行时异常(RuntimeException, 又 ...
- python 两种排序方法 sort() sorted()
python中有两种排序方法,list内置sort()方法或者python内置的全局sorted()方法 区别为: sort()方法对list排序会修改list本身,不会返回新list.sort()只 ...
- 【Java面试真题】剑指Offer53.2——0~n-1中缺失的数字(异或、二分两种解法)
[Java实现]剑指Offer53.2--0~n-1中缺失的数字:面试真题,两种思路分享 前面有另一道面试题[Java实现]剑指offer53.1--在排序数组中查找数字(LeetCode34:在排序 ...
- Java中的两种异常类型是什么?他们有什么区别?
一.Throwable是所有异常的根,java.lang.Throwable Error是错误,java.lang.Error Exception是异常,java.lang.Exception 二.E ...
- mysql 排序长度限制之max_length_for_sort_data以及mysql两种排序算法
SET max_length_for_sort_data = 1024 SHOW VARIABLES LIKE '%max_length_for_sort_data%'; 查询:SELECT * FR ...
随机推荐
- FIRMWARE BUG – THE BIOS HAS CORRUPTED HW-PMU RESOURCES
If you’re trying to install CentOS 7 on HP server and you receive the error from the caption, don’t ...
- Oracle 外键级联更新
Oracle数据库中,外键约束只允许级联删除,不允许级联更新,因此,如果想要实现主表数据更新后,子表外键自动更新,只能取消外键关系,通过前端程序来维护实现完整引用,一个代替的解决方案是使用延迟约束和触 ...
- 使用VISIO远程服务器上的ORACLE数据库,反向生成数据库实体关系图
反向即根据已有的数据库,生成ER图,很多工具都可以实现这一过程,如visio,powerdesigner等,下面文章记录一下我使用VISIO生成远程服务器上的一个数据库ER图过程,供以后自己参考. 1 ...
- (转)Android之发送短信的两种方式
https://www.cnblogs.com/dongweiq/p/4866022.html if(TextUtils.isEmpty(number)||TextUtils.isEmpty(cont ...
- [ZZ]AppiumForWindows 菜鸟计划合集
AppiumForWindows 菜鸟计划 (一) Appium 材料包 AppiumForWindows 菜鸟计划 (二) 源码环境搭建及代码结构 AppiumForWindows 菜鸟计划 (三) ...
- Go语言操作MySQL数据库
Go语言操作MySQL数据库 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用 ...
- @property的使用
1.可以将某个函数变为属性 class Name(): @property def name(self): print('xiaoming') Name().name这里name已经可以当做属性来调用 ...
- 使用shell进行etl数据验证
方法如下: 整理校验的类型,不同的类型配置文件不一样. 1:校验数据增量:需要设置表名,增量字段. 2:非法值校验:设置表名,条件,校验字段,合法值/非法值范围. 3:自定义校验:设置表名,校验名称, ...
- (Python基础)简单购物车代码
以下是最简单,最基础的购物车代码,一起学习,一起参考.product_list = [ ('Iphone',5800), ('Mac Pro',15800), ('car',580000), ('co ...
- Mac 启用NTFS
How to Enable NTFS Write Support in Mac OS X http://osxdaily.com/2013/10/02/enable-ntfs-write-suppor ...