实现Comparable接口对树形结构数据进行排序

背景:

数据库中无序的数据要按树形结构出输出,

如图所示:

每一个记录 对应 一条数据库的 数据,

需求来了,那么怎么实现呢,首先最简单的是直接从数据库 按顺序 查出,然后依次打印,

简单点说吧,oracle数据库有相应的语句可以实现,很容易,但是sql server 没有,尝试了下没有成功,

考虑数据库的兼容性,就像把数据到后台去排序,

那么,这也就是这篇雯所说的内容了,排序。至于排序规则就如图所示很明确了。

。。。割......

刚开始说只需要3级结垢,就是每一个节点下面最多只有两个节点,那好,就直接在

compareTo 写 dept.getParnt().getParent() 这样判断,

过了一段时间又说要4级结构....凌乱... 这个方法我又要重写,

现在写一个通用的,不管多少级都可以

compareTo方法:

@Override
    	public int compareTo(Dept d) {

    		if( this.getRootParent().getId().intValue() != d.getRootParent().getId().intValue() ){
    			//没有相同的parent,那么在不同的根节点之下,按根节点的order排序
    			if(this.getRootParent().getOrder() > d.getRootParent().getOrder()){
    				return 1;
    			}else if(this.getRootParent().getOrder() < d.getRootParent().getOrder()){
    				return -1;
    			}

    		}else{
    			//在同一个根节点下
    			if(isSameBranchAtABranch(d) != null){//在一条线上
    				if( this.getId().intValue() == isSameBranchAtABranch(d).getId().intValue() ){
    					return -1;
    				}else{
    					return 1;
    				}
    			}else{
    				Dept togetherParentFirst = haveSameParentsButBotABranch(d);
    				if(this.getParent().getId().intValue() == togetherParentFirst.getId().intValue()
    					//都是level 2
    						&& d.getParent().getId().intValue() == togetherParentFirst.getId().intValue()){
    					if(this.getOrder().intValue() > d.getOrder().intValue()){
    						return -1;
    					}else if(this.getOrder().intValue() < d.getOrder().intValue()){
    						return 1;
    					}else{
    						return 0;
    					}
    				}
    				Dept temp = this;
    				int orderThis = 0;
    				int orderD = 0;
    				while(temp.getParent() != null){
    					if(temp.getId().intValue() == togetherParentFirst.getId().intValue()){
    						orderThis = temp.getOrder();
    					}else{
    						temp = temp.getParent();
    					}
    				}
    				temp = d;
    				while(temp.getParent() != null){
    					if(temp.getId().intValue() == togetherParentFirst.getId().intValue()){
    						orderD = temp.getOrder();
    					}else{
    						temp = temp.getParent();
    					}
    				}
    				if(orderThis > orderD){
    					return -1;
    				}else if(orderThis < orderD){
    					return 1;
    				}
    			}

    		}

    		return 0;

    	}

完整测试代码:

打印结果如上图所示:

package test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Jtest{

	static ArrayList<Dept> deptList = new ArrayList<Dept>();
	static{
		initData();
	}

	/**
	 * 主程序入口
	 * @param args
	 */
	public static void main(String[] args) {

    	print("===应该的顺序===");
    	iteratorPrintDeptList(deptList);//打印

    	print("===打乱顺序后===");
    	radomSwapList(deptList);

    	iteratorPrintDeptList(deptList);//打印
    	Collections.sort(deptList);//排序

    	print("===排序后===");
    	iteratorPrintDeptListWithLevel(deptList);//打印

    }

    //初始化测试数据
    private static void initData() {
		Jtest jtest = new Jtest();
		//这里写为内部类是因为当时想做个其他的测试,忽略
		Dept deptLevel01_1 = jtest.new Dept(1, "level01_deptLevel01_1", 5, null,null);
		Dept deptLevel01_2 = jtest.new Dept(2, "level01_deptLevel01_2", 4, null,null);
		Dept deptLevel01_3 = jtest.new Dept(3, "level01_deptLevel01_3", 3, null,null);
		Dept deptLevel01_4 = jtest.new Dept(4, "level01_deptLevel01_4", 5, null,null);

		Dept deptLevel02_1 = jtest.new Dept(5, "level02_deptLevel02_1", 9, 1,deptLevel01_1);
		Dept deptLevel02_2 = jtest.new Dept(6, "level02_deptLevel02_2", 5, 1,deptLevel01_1);
		Dept deptLevel02_3 = jtest.new Dept(7, "level02_deptLevel02_3", 6, 1,deptLevel01_1);

		Dept deptLevel02_4 = jtest.new Dept(8, "level02_deptLevel02_4", 6, 2,deptLevel01_2);

		Dept deptLevel02_5 = jtest.new Dept(9, "level02_deptLevel02_5", 6, 3,deptLevel01_3);
		Dept deptLevel02_6 = jtest.new Dept(10, "level02_deptLevel02_6", 8, 3,deptLevel01_3);

		Dept deptLevel03_1 = jtest.new Dept(11, "level03_deptLevel03_1", 6, 8,deptLevel02_4);
		Dept deptLevel03_2 = jtest.new Dept(12, "level03_deptLevel03_2", 8, 8,deptLevel02_4);
		Dept deptLevel03_3 = jtest.new Dept(13, "level03_deptLevel03_3", 6, 5,deptLevel02_1);
		Dept deptLevel03_4 = jtest.new Dept(14, "level03_deptLevel03_4", 8, 5,deptLevel02_1);

		deptList.add(deptLevel01_3);
			deptList.add(deptLevel02_5);
			deptList.add(deptLevel02_6);
		deptList.add(deptLevel01_1);
			deptList.add(deptLevel02_3);
			deptList.add(deptLevel02_2);
			deptList.add(deptLevel02_1);
				deptList.add(deptLevel03_3);
				deptList.add(deptLevel03_4);
		deptList.add(deptLevel01_2);
			deptList.add(deptLevel02_4);
				deptList.add(deptLevel03_1);
				deptList.add(deptLevel03_2);
		deptList.add(deptLevel01_4);
	}

	/**
	 * 打乱list的顺序
	 * @param deptList
	 */
	static void radomSwapList(List<Dept> deptList){
		int size = deptList.size();
		for(int i = 0; i < 30; i++){
			int randomNum = (int)(Math.random()*10);
			if(randomNum >= size){
				continue;
			}
			Dept temp = deptList.get(randomNum);
			deptList.set(randomNum, deptList.get(size - 1 - randomNum));
			deptList.set(size - 1 - randomNum, temp);
		}
	}

	/**
	 * 遍历打印Arraylist
	 * @param deptList
	 */
	static void iteratorPrintDeptList(List<Dept> deptList){
		for(Dept dept : deptList) {
			System.out.println("deptId: "+""+dept.getId() + ", " + dept.getName() + ", " + dept.getParentId());
		}
		print();
	}

	/**
	 * 遍历打印Arraylist(按级别缩进)
	 * @param deptList
	 */
	static void iteratorPrintDeptListWithLevel(List<Dept> deptList){
		for(Dept dept : deptList) {
			int level = dept.getLevel();
			for(int i= 1; i< level; i++){
				System.out.print("--");
			}
			System.out.println("deptId: "+""+dept.getId() + ", " + dept.getName() + ", " + dept.getParentId());
		}
		print();
	}

	/**
	 * 遍历打印Arraylist
	 * @param deptList
	 */
	static void simpleIteratorPrintDeptList(List<Dept> deptList){
		for(Dept dept : deptList) {
			System.out.print(dept.getId() + ", ");
		}
		System.out.println();
	}

	static void print(){
		System.err.println("------------------------");
	}
	static void print(String str){
		System.err.println(str);
	}

    class Dept implements Comparable<Dept>{
    	private Integer id;
    	private String name;
    	private Integer order;
    	private Integer parentId;

    	private Dept parent;

    	/**
    	 * 得到当前部门是第几级部门,parent为null的为 1 级,有一个parent的为2级,依次类推
    	 */
    	private int getLevel(){
    		int temp = 1;
    		Dept tempDept = this;
    		while(tempDept.getParent() != null){
    			tempDept = tempDept.getParent();
    			temp = temp +1;
    		}
    		return temp;
    	}

    	private Dept sameParents(Dept d){

			Dept temp1 = this;
			while(temp1 != null){
				Dept temp2 = d;
				while(temp2 != null){
					if( temp1.getId() == temp2.getId() ){
						return temp1;
					}
					temp2 = temp2.getParent();
				}
				temp1 = temp1.getParent();
			}

			return null;

    	}

    	/**
    	 * 获得根节点的parent
    	 * @return
    	 */
    	private Dept getRootParent(){
    		if(this.getParent() == null){
    			return this;
    		}else{
    			Dept tmp = this;
    			while(tmp.getParent() != null){
    				tmp = tmp.getParent();
        		}
    			return tmp;
    		}

    	}

    	/**
    	 * 得到某个level的parent
    	 * @param level
    	 * @return
    	 */
    	private Dept getParent(int level){

    		int thisLevel = this.getLevel();
    		Dept deptTemp = this;
    		while(deptTemp.getParent() != null){
    			thisLevel = thisLevel - 1;
    			deptTemp = deptTemp.getParent();
    			if(level == thisLevel){
    				return deptTemp;
    			}
    		}
    		return null;
    	}

    	@Override
    	public int compareTo(Dept d) {

    		if( this.getRootParent().getId().intValue() != d.getRootParent().getId().intValue() ){
    			//没有相同的parent,那么在不同的根节点之下,按根节点的order排序
    			if(this.getRootParent().getOrder() > d.getRootParent().getOrder()){
    				return 1;
    			}else if(this.getRootParent().getOrder() < d.getRootParent().getOrder()){
    				return -1;
    			}

    		}else{
    			//在同一个根节点下
    			if(isSameBranchAtABranch(d) != null){//在一条线上
    				if( this.getId().intValue() == isSameBranchAtABranch(d).getId().intValue() ){
    					return -1;
    				}else{
    					return 1;
    				}
    			}else{
    				Dept togetherParentFirst = haveSameParentsButBotABranch(d);
    				if(this.getParent().getId().intValue() == togetherParentFirst.getId().intValue()
    					//都是level 2
    						&& d.getParent().getId().intValue() == togetherParentFirst.getId().intValue()){
    					if(this.getOrder().intValue() > d.getOrder().intValue()){
    						return -1;
    					}else if(this.getOrder().intValue() < d.getOrder().intValue()){
    						return 1;
    					}else{
    						return 0;
    					}
    				}
    				Dept temp = this;
    				int orderThis = 0;
    				int orderD = 0;
    				while(temp.getParent() != null){
    					if(temp.getId().intValue() == togetherParentFirst.getId().intValue()){
    						orderThis = temp.getOrder();
    					}else{
    						temp = temp.getParent();
    					}
    				}
    				temp = d;
    				while(temp.getParent() != null){
    					if(temp.getId().intValue() == togetherParentFirst.getId().intValue()){
    						orderD = temp.getOrder();
    					}else{
    						temp = temp.getParent();
    					}
    				}
    				if(orderThis > orderD){
    					return -1;
    				}else if(orderThis < orderD){
    					return 1;
    				}
    			}

    		}

    		return 0;

    	}
    	/**
    	 * 判断是否两个节点有一个共同的父节点(1)(并且两个节点是在一条分支上,就是一个节点是另一个节点的父节点)
    	 * @param d 要和当前节点比较的节点
    	 * @return 返回父节点(此父节点就是其中的一个节点 )
    	 */

    	private Dept isSameBranchAtABranch(Dept d){
    		Dept temp = this;
    		while(temp.getParent() != null){
    			if( temp.getParent().getId().intValue() == d.getId() ){
    				return d;
    			}
    			temp = temp.getParent();
    		}
    		temp = d;
    		while(temp.getParent() != null){
    			if( temp.getParent().getId().intValue() == this.getId() ){
    				return this;
    			}
    			temp = temp.getParent();
    		}
    		return null;
    	}
    	/**
    	 * 判断是否有相同的父节点(2)(两个节点不位于不同的小分支,此节点不是其中的的任意一个节点,也就是除去1的情况)
    	 * @param d
    	 * @return
    	 */
    	private Dept haveSameParentsButBotABranch(Dept d){

    		Dept temp = this;
    		while(temp.getParent() != null){
    			if(temp.getParent().isSameBranchAtABranch(d) != null){
    				return temp.getParent();
    			}
    			temp = temp.getParent();
    		}
    		return null;
    	}

    	@Override
    	public String toString() {
    		return this.getId()+", "+this.getParent().getParentId()+", "+this.getName();
    	}

    	/**
    	 * 构造函数
    	 * @param id
    	 * @param name
    	 * @param order
    	 * @param parentId
    	 * @param parent
    	 */
    	public Dept(Integer id, String name, Integer order, Integer parentId,Dept parent) {
    		super();
    		this.id = id;
    		this.name = name;
    		this.order = order;
    		this.parentId = parentId;
    		this.parent = parent;
    	}
    	public Integer getId() {
    		return id;
    	}
    	public void setId(Integer id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public Integer getOrder() {
    		return order;
    	}
    	public void setOrder(Integer order) {
    		this.order = order;
    	}
    	public Dept getParent() {
    		return parent;
    	}
    	public void setParent(Dept parent) {
    		this.parent = parent;
    	}
    	public Integer getParentId() {
    		return parentId;
    	}
    	public void setParentId(Integer parentId) {
    		this.parentId = parentId;
    	}
    }
}
时间: 2024-10-20 21:19:28

实现Comparable接口对树形结构数据进行排序的相关文章

13.Java中Comparable接口,Readable接口和Iterable接口

1.Comparable接口 说明:可比较(可排序的) 例子:按照MyClass的y属性进行生序排序 class MyClass implements Comparable<MyClass>{ private int x; private int y; public MyClass(int x,int y){ this.x=x; this.y=y; } @Override public int compareTo(MyClass o) { //按照y进行升序排序 return y<o.y

Java中Comparator接口和Comparable接口的使用

一般情况下在实现对对象元素的数组或集合进行排序的时候会用到Comparator和Comparable接口,通过在元素所在的类中实现这两个接口中的一个,然后对数组或集合调用Arrays.sort或者Collentions.sort方法即可实现对数组或集合的排序.就sort方法里面的参数来说,实现了不同的接口则传递的参数也不尽相同.对于实现了Comparator接口的类来说,sort方法需要接受的参数不仅包括数组或集合,还要包括实现了该接口的类对象:而对实现了Comparable接口的类来说,参数不

Comparable接口的compareTo()方法

[代码] 1 package com.hxl; 2 3 public class Student implements Comparable<Student> { 4 5 private String name; 6 private int age; 7 8 public Student() { 9 super(); 10 } 11 12 public Student(String name, int age) { 13 super(); 14 this.name = name; 15 thi

Comparable接口的使用

功能: Comparable接口可用于对象的排序或者对象的分组 介绍: Comparable接口强行对实现它的类的每个实例进行自然排序,该接口的唯一方法compareTo方法被称为自然比较方法 方法: int compareTo(Object   o)   利用当前对象和传入的目标对象进行比较: 若是当前对象比目标对象大,则返回1,那么当前对象会排在目标对象的后面 若是当前对象比目标对象小,则返回-1,那么当前对象会排在目标对象的后面 若是两个对象相等,则返回0 实例: import java.

【LeetCode】two num 利用comparable接口 对对象进行排序

题目two num 题意:给定一个整数数组和一个目标值,要求在数组中找到两个数,使得它们的和相加等于目标值,并且返回两个数的下标 思路:1.如果使用暴力,时间复杂度为O(n^2) 2.可以先将所有数进行排序,从最大值和最小值开始匹配再根据和目标值的比较移动,知道找到结果,时间复杂度为O(nlog(n)) 知识点:comparable 接口的使用,利用其进行对象的自然排序,相关文章 public class Solution { static class Node implements Compa

浅析Comparable接口和collection的排序

今天LZ在做Huffman编解码,需要做的模块中有一个就是,对于字符出现的frequency来按从小到大顺序排序,然后等下继续构建frequency的排序序列,我最后选用的方案是自己用linkedlist来模拟HuffmanNode队列,那么一个问题就是怎么按照对象的属性来排序. 1):在网上看了发现可以让HuffmanNode类实现Comparable接口,注意的是其中的compareTo(object that)方法,返回的是整数,0,负数.当对象比that大,返回整数:比that小,返回负

java中的排序Comparable接口和Comparator接口

普通的类要实现排序,必须实现Comparable接口,并重写CompareTo()方法. package test; public class Field implements Comparable<Field> {     private String name;     private int age;     public Field() {     }     public Field(String name, int age) {         this.name = name;

Java comparable接口 对象排序

前面写了一篇文章是关于comparator的,那么comparable就必须拿出来做了分析对比. 关于这俩个接口的文章也比较多,本文着重从完整的代码示例去展现说明. OK 首先,还是看下Comparator这里接口的代码: public interface Comparable<T> { /** * Compares this object with the specified object for order. Returns a * negative integer, zero, or a

Comparable接口比较排序 示例

package cn.caijiajia.campaignnew.job; import java.util.ArrayList;import java.util.Collections;import java.util.List;public class Book implements Comparable{ /*编写一个类Book,具有name,price,press,author属性.然后创建5个对象放入ArrayList中,并实现按照price大小排序(使用Comparable接口排序)