Java集合框架里Set子接口概述:TreeSet

—————————————————————
——————————————
Set集合的方法和Collection框架的方法完全相同。

**Set:**元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。
········常用子类:
···············TreeSet: 底层数据结构是二叉树(又称为红黑树)
················HashSet:底层数据结构是哈希表

实现效果:存入时是无序的,但是在打印输出时是会对set集合中的元素进行排序
(按照自然顺序(ASCII),字符串可以称为字典顺序,总之是同一个意思。我这样说应该是不规范的)

对于取出:也是按照二叉树的从左到右依次增大的顺序来取的。

内部实现:无论前面的HashSet还是TreeSet,由于是不包含重复值的,所以其实内部都在调用用于比较的方法。
HashSet使用的比较方法是:HashCode()和equals();
TreeSet使用的方法是
comparable接口的compareTo() 或者 Compartor接口的compare()方法。
前者,让元素具备比较性。即:Student s1,s2; s1.getName().compareTo(s2.getName())
而后者则是让容器具备比较性。(构造方法里接收一个比较器,初始化时就具有比较性。)
后者使用环境:当元素自身不具备比较性,或者具备的比较性无法实现排序,就让容器具备一个比较性。

案例一:实现存入到容器的学生按照年龄进行排序。

/*方法一:	
		1、使用让元素具备比较性的方法;(comparable接口的compareTo())
		2、隐含则年龄相同需要判断姓名是否相同,相同则丢掉,否则按照字典顺序排序;
		*/
		class Student implements Comparable
		{
			private String name;
			private int age;
				//假设函数一初始化就指定姓名和年龄
				Student(String name,int age)
				{
					this.name = name;
					this.age = age;
				}
			//这里只写了get方法,用于获取。开发一般get和set都写
			public String getName()
			{
				return name;
			}
			public int getAge()
			{
				return age;
			}
			//重写比较方法,是不是自定义对象不包含该方法呢?
			public int compareTo(Object obj)
			{
				if(!(obj instanceof Student))
					throw new RuntimeException("Error011:传入对象非Student类型!");
				Student s = (Student)obj;
				//这里注意在判断完年龄相同后,一定要判断一下次要元素。因为年龄相同的人有很多。
				if(this.age>s.age)
					return 1;
				if(this.age==s.age)
				{
					return this.name.compareTo(s.name);
				}
				return -1;
				/*
					同时Integer整数类也重写了CompareTo()方法,
					所以这里我们完全可以这么写:
					(会提示API已经过时了。你懂的,该方法,在新版本可能不建议或者不可以使用了。)
					int num=new Integer(this.getAge()).compareTo(new Integer(s.getAge()));
					if(num==0)
					{
						//String类也实现了compaerTo()方法;
						return this.getName().compareTo(s.getName());
					}
					return num;
				*/
			}
		}
		

主函数:

class TreeSetDemo 
{
	public static void main(String[] args) 
	{
		TreeSet ts = new TreeSet();
		ts.add(new Student("lishi01",20));
		ts.add(new Student("lishi01",21));
		ts.add(new Student("lishi02",21));
		ts.add(new Student("lishi05",20));
		ts.add(new Student("lishi03",25));
		ts.add(new Student("lishi04",21));
		//再来一个重复元素
		ts.add(new Student("lishi02",21));

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

案例二:实现存入到容器的学生按照姓名进行排序。

接下来使用创建比较器的方法:
------在TreeSet集合的API方法里有一个用于结构比较器的构造函数。所以这里我们创建一个比较器类,往容器内部传入该类对象。
Student类:

class Student
{
	private String name;
	private int age;
		//假设函数一初始化就指定姓名和年龄
		Student(String name,int age)
		{
			this.name = name;
			this.age = age;
		}
	//这里只写了get方法,用于获取。开发一般get和set都写
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
}

主函数类:

class TreeSetDemo 
{
	public static void main(String[] args) 
	{
		TreeSet ts = new TreeSet(new MyComparator());
		ts.add(new Student("lishi01",20));
		ts.add(new Student("lishi01",21));
		ts.add(new Student("lishi02",21));
		ts.add(new Student("lishi05",20));
		ts.add(new Student("lishi03",25));
		ts.add(new Student("lishi04",21));
		//再来一个重复元素
		ts.add(new Student("lishi02",21));

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

自定义构造器类:

class MyComparator implements Comparator
{
	//重写该容器的比较方法(被默认调用)
	public int compare(Object obj1,Object obj2)
	{
		if(!(obj1 instanceof Student)||!(obj2 instanceof Student))
			throw new RuntimeException("比较的对象非同一类型");
		//强转为学生类
		Student s1=(Student)obj1;
		Student s2=(Student)obj2;

		//同样这里要注意在判断完姓名相同后,一定要判断一下次要元素。因为姓名相同的人也有。
		int num = s1.getName().compareTo(s2.getName());
		if(num==0)
		{
			return s1.getAge()-s2.getAge();
		}
		return num;
	}
}

结论:
①当两种排序方式都存在时,会默认按照比较器的方式进行排序。
②当想要按照插入顺序倒序打印时,将compare()或者compareTo()这两种方法的内部代码只写return -1;正序只写return 1;
③如果想要排序后再进行倒叙输出:该返回1的返回-1,该返回-1的返回1,就好了。
元素比较性并反向打印写法

			public int compareTo(Object obj)
			{
				if(!(obj instanceof Student))
					throw new RuntimeException("Error011:传入对象非Student类型!");
				Student s = (Student)obj;

//---------------------Start-------------------------------------------
				if(this.age>s.age)
					return -1;
				if(this.age==s.age)
				{
					return s.name.compareTo(this.name);
				}
				return 1;
//---------------------end------------------------------------------
			}

自定义迭代器比较并反向打印写法

public int compare(Object obj1,Object obj2)
	{
		if(!(obj1 instanceof Student)||!(obj2 instanceof Student))
			throw new RuntimeException("比较的对象非同一类型");
		//强转为学生类
		Student s1=(Student)obj1;
		Student s2=(Student)obj2;

//---------------------Start-------------------------------------------
		int num = s1.getName().compareTo(s2.getName());
		if(num==0)
		{
			return s1.getAge()-s2.getAge();
		}
//---------------------end-------------------------------------------
		return num;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值