TreeSet中的排序方式。

TreeSet:可以对集合中的元素进行排序,是不同步的,数据结构为二叉树。判断元素唯一性的方式,就是根据比较方法返回结果是否为0,是0,就相同,不存。

TreeSet对元素进行排序的方式一:让元素自身具备比较功能,即让元素实现Comparable接口,覆盖compare方法。

TreeSet对元素进行排序的方式二:让集合本身具备比较功能,定义一个类实现comparator接口,覆盖compare方法,让该类对象作为参数传递给TreeSet集合的构造函数。


首先我们来看如果没有实现Comparable或者comparator,将对象存入TreeSet会发生什么。

TreeSet<Student> tSet=new TreeSet<>();
		tSet.add(new Student("wujie", 28));
		tSet.add(new Student("wujie1", 27));
		Iterator<Student> iterator=tSet.iterator();
		
		while(iterator.hasNext()){
			Student student=(Student)iterator.next();
			System.out.println(student.getName()+"..."+student.getAge());
		}

控制台输出:Exception in thread "main" java.lang.ClassCastException: firstday.Student cannot be cast to java.lang.Comparable。也就是我们的Student没有实现COmparable,所以treeset并不知道如何去排序。

我们看api中对comparable接口的定义:此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法称为自然比较法。

所以在Student类中实现自定义的comparable方法,如果返回0,两个对象相等,后一个对象不存入。

	@Override
	public int compareTo(Object arg0) {
		Student student=(Student)arg0;
		int temp=this.age-student.age;
		return temp==0?this.name.compareTo(student.name):temp;
		//return 0;
	}

还有第二种方式在什么时候使用呢?如果不要按照对象中具备的自然顺序进行排序,或者对象中不具备自然顺序的时候,我们可以使TreeSet集合自身具备比较功能。即定义一个类实现comparator接口,覆盖compare方法,让该类对象作为参数传递给TreeSet集合的构造函数。

public class Comparator implements java.util.Comparator {

	@Override
	public int compare(Object arg0, Object arg1) {
		Student s1=(Student)arg0;
		Student s2=(Student)arg1;
		
		int temp0=s1.getName().compareTo(s2.getName());
		
		return temp0==0?s1.getAge()-s2.getAge():temp0;
	}

在将比较器传给集合的构造参数

TreeSet<Student> tSet=new TreeSet<>(new Comparator());

当比较器和元素自身的comparable同时存在时,以比较器为主。实际开发中比较器也常用,


最后,上文提到treeset的数据结构为二叉树,也就是通过比较器比较,如果为0,则元素不加入,如果大于0,加入右子树,小于0,加入左子树。




猜你喜欢

转载自blog.csdn.net/qq_37891064/article/details/79590830
今日推荐