java 集合框架-TreeSet

/*
TreeSet可以对Set集合中的对象进行排序;

原理,TreeSet在底层调用了Comparable接口的方法compareTo().
所以,在使用TreeSet存储自定义对象时,要想实现自定义类对象的自然排序,需要类实现Comparable接口,并重写覆盖接口唯一的方法compareTo().

需求:
往TreeSet集合中存储自定义对象学生。
想按照学生的年龄进行排序。

记住:排序时,当主要条件相同时,一定判断一下次要条件。
在本例中,出现了两个同学的年龄是一样的,如果不进行判断次要条件动作,那么会有的学生的信息存储不上,应为在compareTo时返回的是0.
所以,需要继续判断姓名是否一致。在String类中也实现了Comparable接口中的compareTo方法。所以可以直接使用str.compareTo(str1)来实现字符串的比较。

TreeSet的底层数据结构是二叉树的。保存数据唯一性的依据是compareTo方法返回0.

TreeSet排序的第一种方式:让元素自身具备比较性。
元素需要实现Comparable接口,覆盖compareTo方法。
这种方式也称为元素的自然顺序,或者叫做默认顺序。

TreeSet排序的第二种方式:元素本身不具备比较性,那就构造比较器,比较器作为参数传递给TreeSet含参的构造函数。
当两种方式都存在时,以比较器为主。
!!!!!!!!!!!!两种方式的实现在程序TreeSetDemo1.java中!!!!!!!!!!!!!!!!!!
*/


import java.util.*;

class Student implements Comparable//因为TreeSet会对存的对象进行自然排序,其实是它实现了Comparable接口。
{
	private String name;
	private int age;

	Student(String name,int age)
	{
		this.name=name;
		this.age=age;
	}

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

	public int compareTo(Object obj)  //重写接口中的方法,实现按年龄进行排序的功能。
	{
		if(!(obj instanceof Student))
			throw new RuntimeException("不是学生对象");
		
		Student s=(Student)obj;
		TreeSetDemo.sop(this.name+"......"+s.name);
		TreeSetDemo.sop(this.name);   //首先是Lily_01进来并存储在TreeSet集合中。然后是Lily_02进来并与Lily_01进行比较。
		if(this.age>s.age)            //底层调用的是compareTo方法。所以在lily_02进来后,this值得就是Lily_02。说白了就是谁进来this就代表谁。
			return 1;         //大的放在二叉树的右边
		if(this.age==s.age)
		{
			return this.name.compareTo(s.name);  //如果说是一样的话,就不会存储相同的对象。
		}
		return -1;  //小的放在二叉树的左边。
	}
}

class TreeSetDemo 
{
	public static void main(String[] args) 
	{
		TreeSet ts=new TreeSet();
		ts.add(new Student("Lily_01",10));
		ts.add(new Student("Lily_02",9));
		//ts.add(new Student("Lily_03",15));
		//ts.add(new Student("Lily_04",18));
		//ts.add(new Student("Lily_05",5));
		//ts.add(new Student("Lily_06",18));
		//ts.add(new Student("Lily_07",20));

		Iterator it=ts.iterator();
		while(it.hasNext())
		{
			Object obj=it.next();
			Student s=(Student)obj;

			//sop(s.getName()+".."+s.getAge());
		}
		System.out.println("Hello World!");
	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}


/*
总结,TreeSet可以对存入的对象进行自然顺序的排序,
是因为其底层数据结构是二叉树,并且实现了Comparable接口的compareTo()方法。
通过自定义对象的类实现Comparable接口,并覆盖compareTo()方法,即可根据自己的需要存储
有顺序的对象数据。
返回1,说明新进元素较大,放在二叉树的右子节点;
返回-1,说明新进元素较小,放在二叉树的左子节点;
返回0,说明对象元素一致,则再比较其他次要条件(比如姓名一样,就比较年龄)

*/
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 String getName()
	{
		return name;
	}

	public int getAge()
	{
		return age;
	}

	public int compareTo(Object obj)
	{
		/*按照姓名进行排序,如果姓名一样,那就按照年龄进行排序(升序)*/
		if(!(obj instanceof Student))
			throw new RuntimeException("不是学生对象"); 
		Student s=(Student)obj;
		int x=this.name.compareTo(s.name);
		if(x==0)
		{
			if(this.age>s.age)
				return 1;
			if(this.age==s.age)
				return 0;
			return -1;
		}
		return x;
		

		/*
		按照输入的顺序输出:
		return 1;
		*/

		/*
		按照输入的顺序逆序输出:
		return -1;
		*/

		/*
		只存储一个学生的信息:
		return 0;
		*/
	}

}


class TreeSetDemo1 
{
	public static void main(String[] args) 
	{

		TreeSet ts=new TreeSet();//使用方式一:通过实现Comparable接口并覆盖其中的compareTo()方法.
		TreeSet ts=new TreeSet(new MyCompare()); //使用方式二:使用比较器对年龄进行排序。构造比较器实现Comparator接口,并覆盖compare方法。

		ts.add(new Student("Lily",20));		
		ts.add(new Student("Jhon",30));
		ts.add(new Student("Jane",19));
		ts.add(new Student("Sara",17));
		ts.add(new Student("Demetria",25));
		ts.add(new Student("Mike",25));
		ts.add(new Student("Lily",25));

		Iterator it=ts.iterator();
		while(it.hasNext())
		{
			Student s=(Student)it.next();
			sop(s.getName()+","+s.getAge());
		}

		System.out.println("Hello World!");
	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

class MyCompare implements Comparator  //定义比较器,实现按照学生年龄进行排序
{
	public int compare(Object obj1,Object obj2)
	{
		if(!(obj1 instanceof Student)||!(obj2 instanceof Student))
			throw new RuntimeException("有对象不是Student类型的。");
		Student s1=(Student)obj1;
		Student s2=(Student)obj2;
		if(s1.getAge()>s2.getAge())
			return 1;
		if(s1.getAge()==s2.getAge())
			return s1.getName().compareTo(s2.getName());
		return -1;
	}
}


你可能感兴趣的:(java,TreeSet)