黑马程序员——TreeSet排序

                                             ------ >Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


  TreeSet是集合类Set的一种,可以对Set集合中元素进行排序,TreeSet中元素同样是无序的,即存入和取出的顺序不一定一致,元素不可重复,TreeSet中的对象必须具备比较性,元素不可重复,保证元素唯一性的依据是compareTo方法和return 0。TreeSet存储对象的时候, 可以排序, 但是需要指定排序的算法,Integer能排序(有默认顺序), String能排序(有默认顺序), 自定义的类存储的时候出现异常(没有顺序),如果想把自定义类的对象存入TreeSet进行排序, 那么必须实现Comparable接口,

 *   在类上implement Comparable
 *   重写compareTo()方法
 *   在方法内定义比较算法, 根据大小关系, 返回正数负数或零
 *   在使用TreeSet存储对象的时候, add()方法内部就会自动调用compareTo()方法进行比较, 根据比较结果使用二叉树形式进行存储

   首先介绍TreeSet排序的第一种方式:让元素自身具备比较性元素需事先compareTo接口,覆盖compareTo方法,这种方式称为元素的自然顺序,或者叫默认顺序,举例:

/*
TreeSet可以对集合中元素排序
需求:往TreeSet集合中存储自定义对象学生,
按照学生年龄排序 
*/
import java.util.*;
class  TreeSetDemo
{
	public static void main(String[] args) 
	{
		
		TreeSet ts=new TreeSet();
		ts.add(new Student("lisi03",22) );
		ts.add(new Student("lisi007",21) );
		ts.add(new Student("lisi06",28) );
		ts.add(new Student("lisi01",26) );
		ts.add(new Student("lisi02",26) );

		Iterator it=ts.iterator();

		while (it.hasNext())
		{
			Student stu=(Student)it.next();
			System.out.println(stu.getName()+"..."+stu.getAge());
		}	

	}
}

class Student implements  Comparable //该接口强制让学生具备比较性

	{
		private String name;
		private int age;
		Student(String name,int age)
		{
			this.name=name;
			this.age=age;
		}
		public int compareTo(Object obj)
		{
			//return  1;  //  取出顺序和存放顺序相同,二叉树
			
		 	if(!(obj instanceof Student) )
				throw new RuntimeException("不是学生对象");
			Student s=(Student) obj; //强制转换为学生

			System.out.println(this.name+"..."+s.name);
			if(this.age>s.age)
				return 1;
			if(this.age==s.age)
			{
				return this.name.compareTo(s.name);  //主要条件相同时,一定要判断次要条件
			}
			return -1;   

		}
		public String getName()
		{
			return name;
		}
		public int getAge()
		{
			return age;
		}

	}

程序运行后,就会输出按照年龄排序的结果。

  TreeSet中底层数据结构是二叉树,这样节省比较次数,默认的取出方式是从小到大。

     排序的第二种方式:
当元素自身不具备比较性时,或者具备的比较性不是所需的,这时让集合自身具备比较性,在集合初始化时,就有比较方式,采取构造函数,定义比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。当两种方式都存在是,以比较器为主,定义一个类,实现Comparator接口,覆盖compare方法。实现代码如下:

 
import java.util.*;
class Student implements  Comparable //该接口强制让学生具备比较性  ,按年龄排序

	{
		private String name;
		private int age;
		Student(String name,int age)
		{
			this.name=name;
			this.age=age;
		}
		public int compareTo(Object obj)
		{
			//return  1;  //  取出顺序和存放顺序相同,二叉树
			
		 	if(!(obj instanceof Student) )
				throw new RuntimeException("不是学生对象");
			Student s=(Student) obj; //强制转换为学生

			System.out.println(this.name+"..."+s.name);
			if(this.age>s.age)
				return 1;
			if(this.age==s.age)
			{
				return this.name.compareTo(s.name);  //主要条件相同时,一定要判断次要条件
			}
			return -1;   

		}
		public String getName()
		{
			return name;
		}
		public int getAge()
		{
			return age;
		}

	}


class  TreeSetDemo2
{
	public static void main(String[] args) 
	{
		 TreeSet ts=new TreeSet(new Mycompare());  //按姓名排序
	//	TreeSet ts=new TreeSet( );           //按年龄排序
		ts.add(new Student("lisi03",22) );
		ts.add(new Student("lisi007",21) );
		ts.add(new Student("lisi06",28) );
		ts.add(new Student("lisi01",26) );
		ts.add(new Student("lisi02",26) );
		ts.add(new Student("lisi03",23) );

		Iterator it=ts.iterator();

		while (it.hasNext())
		{
			Student stu=(Student)it.next();
			System.out.println(stu.getName()+"..."+stu.getAge());
		}	

	}
}

class Mycompare implements Comparator   //按姓名排序
{
	public int compare(Object o1,Object o2)
	{
		Student s1=(Student)o1;
		Student s2=(Student)o2; //强制装换为Student

		int num =s1.getName().compareTo(s2.getName());
		if (num==0)      //姓名相同时,按年龄排序,即主要条件相同时,判断次要条件
		{
			
			// return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge())); //另一种较简便写法
		 	if(s1.getAge()>s2.getAge())
				return 1;
			if(s1.getAge()==s2.getAge())
				return 0;
			return -1;   
		}

		return num;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值