java List递归排序,无序的列表按照父级关系进行排序(两种排序类型)

当有一个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 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 + "]";
	}

}

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

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 dept = new Dept();

		dept = new Dept();
		dept.setId("122");
		dept.setName("三级b");
		dept.setParentid("12");
		originalList.add(dept);

		dept = new Dept();
		dept.setId("13");
		dept.setName("二级b");
		dept.setParentid("1");
		originalList.add(dept);

		dept = new Dept();
		dept.setId("121");
		dept.setName("三级a");
		dept.setParentid("12");
		originalList.add(dept);

		dept = new Dept();
		dept.setId("1");
		dept.setName("一级");
		originalList.add(dept);

		dept = new Dept();
		dept.setId("131");
		dept.setName("三级c");
		dept.setParentid("13");
		originalList.add(dept);

		dept = new Dept();
		dept.setId("12");
		dept.setName("二级a");
		dept.setParentid("1");
		originalList.add(dept);

		dept = new Dept();
		dept.setId("132");
		dept.setName("三级d");
		dept.setParentid("13");
		originalList.add(dept);

		List<Dept> resultList = 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]]

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

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--
        }
    }

    void addToMap(Integer level, Dept dept) {
        if (Objects.isNull(treeMap.get(level)))
            treeMap.put(level, new ArrayList<Dept>());  //若treeMap中无等级
        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();
    }

    public static void main(String[] args) {
        List<Dept> originalList = new ArrayList<>();
        Dept dept = new Dept();

        dept = new Dept();
		dept.setId("122");
		dept.setName("三级b");
		dept.setParentid("12");
		originalList.add(dept);

		dept = new Dept();
		dept.setId("13");
		dept.setName("二级b");
		dept.setParentid("1");
		originalList.add(dept);

		dept = new Dept();
		dept.setId("121");
		dept.setName("三级a");
		dept.setParentid("12");
		originalList.add(dept);

		dept = new Dept();
		dept.setId("1");
		dept.setName("一级");
		originalList.add(dept);

		dept = new Dept();
		dept.setId("131");
		dept.setName("三级c");
		dept.setParentid("13");
		originalList.add(dept);

		dept = new Dept();
		dept.setId("12");
		dept.setName("二级a");
		dept.setParentid("1");
		originalList.add(dept);

		dept = new Dept();
		dept.setId("132");
		dept.setName("三级d");
		dept.setParentid("13");
		originalList.add(dept);

        List<Dept> resultList = DeptSort2.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://www.cnblogs.com/hooly/p/8810865.html

时间: 2024-10-20 16:29:31

java List递归排序,无序的列表按照父级关系进行排序(两种排序类型)的相关文章

两种排序方法(直接判断)

题目描述 考拉有n个字符串字符串,任意两个字符串长度都是不同的.考拉最近学习到有两种字符串的排序方法: 1.根据字符串的字典序排序.例如:"car" < "carriage" < "cats" < "doggies < "koala"2.根据字符串的长度排序.例如:"car" < "cats" < "koala" <

HashMap的两种排序方式

Map<String, Integer> map = new HashMap<String, Integer>(); map.put("d", 2); map.put("c", 1); map.put("b", 1); map.put("a", 3); List<Map.Entry<String, Integer>> infoIds = new ArrayList<Map.

经典的两种排序算法

一.冒泡排序 int temp = 0; for (int j = 1; j < a.Length; j++) { for (int i = 0; i < a.Length - j; i++)//内循环,每走一趟会把最小值放到最后 { if (a[i] < a[i + 1]) { temp = a[i]; a[i] = a[i + 1]; a[i + 1] = temp; } } } 二.选择法排序 int min; for (int j = 0; j< a.Length; j++

算法—比较两种排序算法:选择排序和插入排序

现在我们已经实现了两种排序算法,我们很自然地想知道选择排序和插入排序哪种更快.这里我们第一次用实践说明我们解决这个问题的办法. 性质:对于随机排序的无重复主键的数组,插入排序和选择排序的运行时间是平方级别的,两者之比应该是一个较小的常数. 例证:这个结论在过去的半个世纪中已经在许多不同类型的计算机上经过了验证.在1980年本书第一版完成之时插入排序就比选择排序快一倍,现在仍然是这样,尽管那时这些算法将10万条数据排序需要几个小时而现在只需要几秒钟.在你的计算机上插入排序也比选择排序快一些吗?可以

两种排序方法 网易2017内推编程题

考拉有n个字符串字符串,任意两个字符串长度都是不同的.考拉最近学习到有两种字符串的排序方法: 1.根据字符串的字典序排序.例如: "car" < "carriage" < "cats" < "doggies < "koala" 2.根据字符串的长度排序.例如: "car" < "cats" < "koala" < &

Map两种遍历方式与TreeSet两种排序依据

集合:可以存储不同类型的多个对象,随着存储对象的个数的增加而自动扩大容量   体系结构: Collection<E>   |----List:存入的对象是有序的,且可以重复           ArrayList:底层使用的数据结构是数组,线程不安全的,查找速度快,增删速度慢           Vector:底层使用的数据结构是数组,线程安全的,查找速度快,增删速度慢           LinkedList:底层使用的数据结构是链表,线程不安全的,查找速度慢,增删速度快     |----

java-实现两种排序方法

/*对给定数组进行排序{5,7,2,8,9,1,3,4} */class ArrayTest2{/*选择排序内循环结束一次,最值出现在头角标位置上*/public static void SelectSort(int[] arr){for(int x=0;x<arr.length-1;x++){for(int y=1+x;y<arr.length;y++){if(arr[x]>arr[y]){/*int temp=arr[x];arr[x]=arr[y];arr[y]=temp;*/sw

mysql 排序长度限制之max_length_for_sort_data以及mysql两种排序算法

SET max_length_for_sort_data = 1024 SHOW VARIABLES LIKE '%max_length_for_sort_data%'; 查询:SELECT * FROM CS_COLUMNS ORDER BY table_name,column_name LIMIT 0,100 错误代码: 1815Internal error: IDB-2015: Sorting length exceeded. Session variable max_length_for

十四、Python的自定义排序 以及两种排序方式

data_list = [] data_list.append({'softname':'1','version':'1.2.2.2'}) data_list.append({'softname':'7','version':'1.2.2.2'}) data_list.append({'softname':'5','version':'1.2.2.2'}) data_list.append({'softname':'2','version':'1.2.2.2'}) data_list.appen