当前位置:   article > 正文

java List递归排序,传统方式和java8 Stream优化递归,无序的列表按照父级关系进行排序(两种排序类型)...

java stream 递归

当有一个List列表是无序的,List中的数据有parentid进行关联,通过java排序成两种排序类型:

注意:所用的测试列表最顶级 无 parentid ,若为特殊值,修改下判断方法即可。

测试实体类:

  1. /**
  2. * <p>部门列表排序测试类<p>
  3. * @version 1.0
  4. * @author li_hao
  5. * @date 2018年4月12日
  6. */
  7. public class Dept {
  8. private String id; //id
  9. private String name; //名称
  10. private String parentid; //父级id
  11. public Dept(){
  12. super();
  13. }
  14. public Dept(String id, String name, String parentid) {
  15. super();
  16. this.id = id;
  17. this.name = name;
  18. this.parentid = parentid;
  19. }
  20. public String getId() {
  21. return id;
  22. }
  23. public void setId(String id) {
  24. this.id = id;
  25. }
  26. public String getName() {
  27. return name;
  28. }
  29. public void setName(String name) {
  30. this.name = name;
  31. }
  32. public String getParentid() {
  33. return parentid;
  34. }
  35. public void setParentid(String parentid) {
  36. this.parentid = parentid;
  37. }
  38. @Override
  39. public String toString() {
  40. return "TestSort [id=" + id + ", name=" + name + ", parentid=" + parentid + "]";
  41. }
  42. }

第一种排序:按照树结构进行排序

排序前: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]]

排序代码(第一种排序):

1. 传统方式:
  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.Objects;
  4. import org.apache.commons.lang.StringUtils;
  5. /**
  6. * <p>列表排序,按照树结构排序list(顶级无父节点)<p>
  7. * 排序前:122,13,121,1,131,12,132...
  8. * 无序的
  9. * [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]]
  10. *
  11. * 排序后:1,13,131,132,12,122,121...
  12. * 按照树结构排序
  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]]
  14. * @version 1.0
  15. * @author li_hao
  16. * @date 2018年4月12日
  17. */
  18. public class DeptSort {
  19. private List<Dept> resultList = new ArrayList<>(); //输出列表
  20. private List<Dept> deptList; //输入列表
  21. /**
  22. * 排序
  23. * @param deptList
  24. */
  25. public DeptSort(List<Dept> deptList){
  26. this.deptList = deptList;
  27. for(Dept dept : this.deptList){
  28. if(StringUtils.isBlank(dept.getParentid())){ //当父级为空
  29. resultList.add(dept); //当父级为空时即顶级,首先放入输出列表
  30. findChildren(dept); //查询下级
  31. }
  32. }
  33. }
  34. /**
  35. * 查询下级
  36. * @param dept
  37. */
  38. private void findChildren(Dept dept){
  39. List<Dept> childrenList = new ArrayList<>();
  40. //遍历输入列表,查询下级
  41. for(Dept d : deptList){
  42. if(Objects.equals(dept.getId(), d.getParentid()))
  43. childrenList.add(d);
  44. }
  45. //遍历到最末端,无下级,退出遍历
  46. if(childrenList.isEmpty()){
  47. return;
  48. }
  49. //对下级进行遍历
  50. for(Dept d : childrenList){
  51. resultList.add(d);
  52. findChildren(d);
  53. }
  54. }
  55. public List<Dept> getResultList(){
  56. return resultList;
  57. }
  58. public static List<Dept> sort(List<Dept> originalList){
  59. return new DeptSort(originalList).getResultList();
  60. }
  61. /**
  62. * 测试
  63. * @param args
  64. */
  65. public static void main(String[] args) {
  66. List<Dept> originalList = new ArrayList<Dept>();
  67. originalList.add(new Dept("122", "三级b", "12"));
  68. originalList.add(new Dept("13", "二级b", "1"));
  69. originalList.add(new Dept("121", "三级a", "12"));
  70. originalList.add(new Dept("1", "一级", null));
  71. originalList.add(new Dept("131", "三级c", "13"));
  72. originalList.add(new Dept("12", "二级a", "1"));
  73. originalList.add(new Dept("132", "三级d", "13"));
  74. List<Dept> resultList = DeptSort.sort(originalList);
  75. System.out.println("输入列表:"+ originalList);
  76. System.out.println("输出列表:"+ resultList);
  77. }
  78. }
2. java8 Stream优化递归:
  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.Objects;
  4. import java.util.stream.Collectors;
  5. import java.util.stream.Stream;
  6. import org.apache.commons.lang.StringUtils;
  7. /**
  8. * java8 Stream 优化递归
  9. * <p>列表排序,按照树结构排序list(顶级无父节点)<p>
  10. * 排序前:122,13,121,1,131,12,132...
  11. * 无序的
  12. * [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]]
  13. *
  14. * 排序后:1,13,131,132,12,122,121...
  15. * 按照树结构排序
  16. * [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]]
  17. * @version 1.0
  18. * @author li_hao
  19. * @date 2018年4月12日
  20. */
  21. public class DeptSortJava8 {
  22. private List<Dept> deptList;
  23. public DeptSortJava8(List<Dept> deptList) {
  24. this.deptList = deptList;
  25. }
  26. public static List<Dept> sort(List<Dept> originalList) {
  27. return new DeptSortJava8(originalList).sort();
  28. }
  29. private List<Dept> sort() {
  30. return this.deptList.stream()
  31. .filter(d -> StringUtils.isBlank(d.getParentid()))
  32. .flatMap(d -> Stream.concat(Stream.of(d), findChildren(d)))
  33. .collect(Collectors.toList());
  34. }
  35. /**
  36. * 查询下级部门
  37. * @param dept
  38. */
  39. private Stream<Dept> findChildren(Dept dept) {
  40. return deptList.stream()
  41. .filter(d -> Objects.equals(dept.getId(), d.getParentid()))
  42. .flatMap(d -> Stream.concat(Stream.of(d), findChildren(d)));
  43. }
  44. /**
  45. * 测试
  46. * @param args
  47. */
  48. public static void main(String[] args) {
  49. List<Dept> originalList = new ArrayList<Dept>();
  50. originalList.add(new Dept("122", "三级b", "12"));
  51. originalList.add(new Dept("13", "二级b", "1"));
  52. originalList.add(new Dept("121", "三级a", "12"));
  53. originalList.add(new Dept("1", "一级", null));
  54. originalList.add(new Dept("131", "三级c", "13"));
  55. originalList.add(new Dept("12", "二级a", "1"));
  56. originalList.add(new Dept("132", "三级d", "13"));
  57. List<Dept> resultList = DeptSortJava8.sort(originalList);
  58. System.out.println("输入列表:"+ originalList);
  59. System.out.println("输出列表:"+ resultList);
  60. }
  61. }

测试结果:

排序前:

[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. 传统方式:
  1. import java.util.ArrayList;
  2. import java.util.Iterator;
  3. import java.util.List;
  4. import java.util.Objects;
  5. import java.util.TreeMap;
  6. import org.apache.commons.lang.StringUtils;
  7. /**
  8. *
  9. * <p>列表排序,按照层级从上到下排序list,同级的放一块(顶级无父节点)<p>
  10. * * 排序前:122,13,121,1,131,12,132...
  11. * 无序的
  12. * [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]]
  13. *
  14. * 排序后:1,13,12,131,132,122,121...
  15. * 按照层级排序
  16. * [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]]
  17. * @version 1.0
  18. * @author li_hao
  19. * @date 2018年4月12日
  20. */
  21. public class DeptSort2 {
  22. private TreeMap<Integer, List<Dept>> treeMap; //定义一个treeMap,key是等级,value是当前的等级对应的所有对象list
  23. private Integer level = 2;
  24. private List<Dept> resultList = new ArrayList(); //输出列表
  25. private List<Dept> deptList; //输入列表
  26. /**
  27. * 排序
  28. * @param deptList
  29. */
  30. public DeptSort2(List<Dept> deptList) {
  31. this.deptList = deptList;
  32. for (Dept dept : this.deptList) {
  33. if (StringUtils.isBlank(dept.getParentid())) { //当父级为空
  34. resultList.add(dept); //当父级为空时即顶级,首先放入输出列表
  35. treeMap = new TreeMap<>();
  36. findChildren(dept); //查询下级
  37. Iterator it = treeMap.keySet().iterator(); //迭代treeMap
  38. while (it.hasNext()) { //检查序列中是否还有元素,如果迭代中还有元素返回true(因为treeMap中放的是2级和2级下面的所有list,所以只需要判断it.hashNext)
  39. resultList.addAll(treeMap.get(it.next())); //把treeMap中所有的list按照层级顺序添加到resultList中
  40. }
  41. }
  42. }
  43. }
  44. /**
  45. * 查询下级部门
  46. * 方法进去的时候就记录当前层级数,findchildren方法走完的时候,表示这一层已经没有逻辑了,递归回上一层,所以 this点level减一
  47. * @param dept
  48. */
  49. private void findChildren(Dept dept) {
  50. Integer level = this.level++; //第一次进来时level值为2,this.level值为3
  51. try {
  52. List<Dept> childrenList = new ArrayList<>();
  53. //遍历输入列表,查询下级
  54. for (Dept d : deptList) {
  55. if (Objects.equals(dept.getId(), d.getParentid()))
  56. childrenList.add(d);
  57. }
  58. //遍历到最末端,无下级,退出遍历
  59. if (childrenList.isEmpty()) {
  60. return;
  61. }
  62. //对下级进行遍历
  63. for (Dept d : childrenList) {
  64. addToMap(level, d); //向treeMap中添加等级和对应dept(第一次执行的level值为2)
  65. findChildren(d); //查询下级,(比如:第一次进来时level值为2,this.level值为3,在进入此方法后,level为3,this.level为4,没查到则跳出,level减一)
  66. }
  67. } finally {
  68. this.level--; //由于再次执行findChildren时,this.level的值+1了,那么在执行完毕后需要finally:this.level--
  69. }
  70. }
  71. /**
  72. * 向treeMap中添加等级和对应的List
  73. * @param level
  74. * @param dept
  75. */
  76. void addToMap(Integer level, Dept dept) {
  77. if (Objects.isNull(treeMap.get(level)))
  78. treeMap.put(level, new ArrayList<Dept>()); //先判断下对应层级在map里有没有,没有就初始化,给个list
  79. treeMap.get(level).add(dept); //若treeMap中有等级,则添加dept
  80. }
  81. public List<Dept> getResultList() {
  82. return resultList;
  83. }
  84. public static List<Dept> sort(List<Dept> originalList) {
  85. return new DeptSort2(originalList).getResultList();
  86. }
  87. /**
  88. * 测试
  89. * @param args
  90. */
  91. public static void main(String[] args) {
  92. List<Dept> originalList = new ArrayList<Dept>();
  93. originalList.add(new Dept("122", "三级b", "12"));
  94. originalList.add(new Dept("13", "二级b", "1"));
  95. originalList.add(new Dept("121", "三级a", "12"));
  96. originalList.add(new Dept("1", "一级", null));
  97. originalList.add(new Dept("131", "三级c", "13"));
  98. originalList.add(new Dept("12", "二级a", "1"));
  99. originalList.add(new Dept("132", "三级d", "13"));
  100. List<Dept> resultList = DeptSort2.sort(originalList);
  101. System.out.println("输入列表:"+ originalList);
  102. System.out.println("输出列表:"+ resultList);
  103. }
  104. }
2. java8 Stream优化递归:
  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.Objects;
  4. import java.util.stream.Collectors;
  5. import org.apache.commons.lang.StringUtils;
  6. /**
  7. * java8 Stream 优化递归
  8. * <p>列表排序,按照层级从上到下排序list,同级的放一块(顶级无父节点)<p>
  9. * * 排序前:122,13,121,1,131,12,132...
  10. * 无序的
  11. * [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]]
  12. *
  13. * 排序后:1,13,12,131,132,122,121...
  14. * 按照层级排序
  15. * [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]]
  16. * @version 1.0
  17. * @author li_hao
  18. * @date 2018年4月12日
  19. */
  20. public class DeptSortJava82 {
  21. private List<Dept> deptList;
  22. private List<Dept> resultList = new ArrayList<>();
  23. public DeptSortJava82(List<Dept> deptList) {
  24. this.deptList = deptList;
  25. }
  26. public static List<Dept> sort(List<Dept> originalList) {
  27. return new DeptSortJava82(originalList).sort();
  28. }
  29. private List<Dept> sort() {
  30. this.deptList.stream()
  31. .filter(d -> StringUtils.isBlank(d.getParentid()))
  32. .forEach(d -> {
  33. resultList.add(d);
  34. findChildren(d);
  35. });
  36. return resultList;
  37. }
  38. /**
  39. * 查询下级部门
  40. *
  41. * @param dept
  42. */
  43. private void findChildren(Dept dept) {
  44. List<Dept> childrenList = deptList.stream()
  45. .filter(d -> Objects.equals(dept.getId(), d.getParentid()))
  46. .collect(Collectors.toList());
  47. if (childrenList.isEmpty())
  48. /* 跳出递归 */
  49. return;
  50. else
  51. childrenList.forEach(d -> {
  52. resultList.add(d);
  53. findChildren(d);
  54. });
  55. }
  56. public static void main(String[] args) {
  57. List<Dept> originalList = new ArrayList<Dept>();
  58. originalList.add(new Dept("122", "三级b", "12"));
  59. originalList.add(new Dept("13", "二级b", "1"));
  60. originalList.add(new Dept("121", "三级a", "12"));
  61. originalList.add(new Dept("1", "一级", null));
  62. originalList.add(new Dept("131", "三级c", "13"));
  63. originalList.add(new Dept("12", "二级a", "1"));
  64. originalList.add(new Dept("132", "三级d", "13"));
  65. List<Dept> resultList = DeptSortJava82.sort(originalList);
  66. System.out.println("输入列表:"+ originalList);
  67. System.out.println("输出列表:"+ resultList);
  68. }
  69. }
测试结果:

排序前:

[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/SummerGaoPlus/sortdemo

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/116094
推荐阅读
相关标签
  

闽ICP备14008679号