当有一个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]]
测试实体类:
/***
部门列表排序测试类
*@version1.0
*@authorli_hao
* @date 2018年4月12日*/
public classDept {private String id; //id
private String name; //名称
private String parentid; //父级id
publicDept(){super();
}publicDept(String id, String name, String parentid) {super();this.id =id;this.name =name;this.parentid =parentid;
}publicString getId() {returnid;
}public voidsetId(String id) {this.id =id;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}publicString getParentid() {returnparentid;
}public voidsetParentid(String parentid) {this.parentid =parentid;
}
@OverridepublicString toString() {return "TestSort [id=" + id + ", name=" + name + ", parentid=" + parentid + "]";
}
}
排序代码(第一种排序):
1. 传统方式:
importjava.util.ArrayList;importjava.util.List;importjava.util.Objects;importorg.apache.commons.lang.StringUtils;/***
列表排序,按照树结构排序list(顶级无父节点)
* 排序前: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]]
*@version1.0
*@authorli_hao
* @date 2018年4月12日*/
public classDeptSort {private List resultList = new ArrayList<>(); //输出列表
private List deptList; //输入列表
/*** 排序
*@paramdeptList*/
public DeptSort(ListdeptList){this.deptList =deptList;for(Dept dept : this.deptList){if(StringUtils.isBlank(dept.getParentid())){ //当父级为空
resultList.add(dept); //当父级为空时即顶级,首先放入输出列表
findChildren(dept); //查询下级
}
}
}/*** 查询下级
*@paramdept*/
private voidfindChildren(Dept dept){
List 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 ListgetResultList(){returnresultList;
}public static List sort(ListoriginalList){return newDeptSort(originalList).getResultList();
}/*** 测试
*@paramargs*/
public static voidmain(String[] args) {
List originalList = new ArrayList();
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 resultList =DeptSort.sort(originalList);
System.out.println("输入列表:"+originalList);
System.out.println("输出列表:"+resultList);
}
}
2. java8 Stream优化递归:
importjava.util.ArrayList;importjava.util.List;importjava.util.Objects;importjava.util.stream.Collectors;importjava.util.stream.Stream;importorg.apache.commons.lang.StringUtils;/*** java8 Stream 优化递归
*
列表排序,按照树结构排序list(顶级无父节点)
* 排序前: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]]
*@version1.0
*@authorli_hao
* @date 2018年4月12日*/
public classDeptSortJava8 {private ListdeptList;public DeptSortJava8(ListdeptList) {this.deptList =deptList;
}public static List sort(ListoriginalList) {return newDeptSortJava8(originalList).sort();
}private Listsort() {return this.deptList.stream()
.filter(d->StringUtils.isBlank(d.getParentid()))
.flatMap(d->Stream.concat(Stream.of(d), findChildren(d)))
.collect(Collectors.toList());
}/*** 查询下级部门
*@paramdept*/
private StreamfindChildren(Dept dept) {returndeptList.stream()
.filter(d->Objects.equals(dept.getId(), d.getParentid()))
.flatMap(d->Stream.concat(Stream.of(d), findChildren(d)));
}/*** 测试
*@paramargs*/
public static voidmain(String[] args) {
List originalList = new ArrayList();
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 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. 传统方式:
importjava.util.ArrayList;importjava.util.Iterator;importjava.util.List;importjava.util.Objects;importjava.util.TreeMap;importorg.apache.commons.lang.StringUtils;/***
*
列表排序,按照层级从上到下排序list,同级的放一块(顶级无父节点)
* * 排序前: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]]
*@version1.0
*@authorli_hao
* @date 2018年4月12日*/
public classDeptSort2 {private TreeMap> treeMap; //定义一个treeMap,key是等级,value是当前的等级对应的所有对象list
private Integer level = 2;private List resultList = new ArrayList(); //输出列表
private List deptList; //输入列表
/*** 排序
*@paramdeptList*/
public DeptSort2(ListdeptList) {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减一
*@paramdept*/
private voidfindChildren(Dept dept) {
Integer level= this.level++; //第一次进来时level值为2,this.level值为3
try{
List 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
*@paramlevel
*@paramdept*/
voidaddToMap(Integer level, Dept dept) {if(Objects.isNull(treeMap.get(level)))
treeMap.put(level,new ArrayList()); //先判断下对应层级在map里有没有,没有就初始化,给个list
treeMap.get(level).add(dept);//若treeMap中有等级,则添加dept
}public ListgetResultList() {returnresultList;
}public static List sort(ListoriginalList) {return newDeptSort2(originalList).getResultList();
}/*** 测试
*@paramargs*/
public static voidmain(String[] args) {
List originalList = new ArrayList();
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 resultList =DeptSort2.sort(originalList);
System.out.println("输入列表:"+originalList);
System.out.println("输出列表:"+resultList);
}
}
2. java8 Stream优化递归:
importjava.util.ArrayList;importjava.util.List;importjava.util.Objects;importjava.util.stream.Collectors;importorg.apache.commons.lang.StringUtils;/*** java8 Stream 优化递归
*
列表排序,按照层级从上到下排序list,同级的放一块(顶级无父节点)
* * 排序前: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]]
*@version1.0
*@authorli_hao
* @date 2018年4月12日*/
public classDeptSortJava82 {private ListdeptList;private List resultList = new ArrayList<>();public DeptSortJava82(ListdeptList) {this.deptList =deptList;
}public static List sort(ListoriginalList) {return newDeptSortJava82(originalList).sort();
}private Listsort() {this.deptList.stream()
.filter(d->StringUtils.isBlank(d.getParentid()))
.forEach(d->{
resultList.add(d);
findChildren(d);
});returnresultList;
}/*** 查询下级部门
*
*@paramdept*/
private voidfindChildren(Dept dept) {
List childrenList =deptList.stream()
.filter(d->Objects.equals(dept.getId(), d.getParentid()))
.collect(Collectors.toList());if(childrenList.isEmpty())/*跳出递归*/
return;elsechildrenList.forEach(d->{
resultList.add(d);
findChildren(d);
});
}public static voidmain(String[] args) {
List originalList = new ArrayList();
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 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]]