关闭

黑马程序员——TreeSet集合添加元素的原理

标签: java语言
703人阅读 评论(0) 收藏 举报
分类:

TreeSet集合是树集(二叉树)数据结构,其在向集合中存入元素时,会将存入的元素与树集上的元素进行对比,如果此元素在树集上不存在,那么在对比后会将此元素存入树集上适当的位置。那么此元素与树集上元素的对比的原理是什么?

 

Comparable接口实现排序:

 

       在默认情况下,树集每插入一个元素会调用此元素的compareTo方法来和树集中的元素依次对比,因此javacompareTo方法抽取出来,形成一个接口Comparable,此接口仅仅封装了一个方法,此接口内部代码为:

Public     interface        Comparable

{

              int   compareTo(T other);

}

那么在向树集添加元素时,这个方法的调用过程是怎样的?

假定树集中有一个元素b,我们要想树集中添加一个元素a,那么会调用acompareTo()方法来和b比较,即a.compareTo(b),如果元素a与元素b相等,则此方法一定返回0,树集将不将a存入树集,如果元素a大于元素b的话,则此方法返回一个正值(具体的返回值不重要,关键是值的符号),然后元素a会与树集中元素b右边的元素继续比较,如果在树集中元素b右边并没有元素,则会将元素a存在b的右边。如果元素a小于元素b,则此方法会返回一个负值,然后元素a会与树集中元素b左边的元素继续比较,如果在树集中元素b左边并没有元素,则会将元素a存在b的左边。

如果我们要向树集中存入我们自定义的对象,那么我们的这个对象就必须通过实现Comparable接口来自定义排列存入树集中的顺序。在Object中并没有提供任何comparable接口的默认实现。

例如,下面代码的就实现了如何使用id来对Student对象进行排序:

class   Student  implements  Comparable

{

       int  id;

       String  name

       Student(int id , String  name )

{

       this.id=id;

       this.name=name;

}

       Public  int  compareTo(Student stu)

{

       return  id  stu.id;

}

}    

需要注意的是 return    变量  对象.变量 这样的语句在有些情况下不可以使用的,例如:变量为一个足够大的正整数,对象.变量为一个足够大的负整数,两数相减就有可能会溢出。

 

Comparator接口实现排序:

       让对象实现Comparable接口定义其在树集中的排序方式固然是可以的,但是当我们不想用此排序方式,想用另外的排序方式来实现其在树集中的排序就不行了,例如在上述Student 类中 我们不想用学生的 id 来实现树集中的排序,我们想用学生的 name 来实现排序,那么我们就要重写 Student 类了,但是在实际开发中是不可能让我们重写 Student 类的,因为 Student 类已经被封装。另外即使我们可以重写此类,我们也不可能改变一次排序方式重写一次 Student 类。另外还有一种情况是我们需要对一个类的对象进行排序,但是这个类的创建者有没有实现Comparable接口。那我们该怎么办?

       在这种情况下,我们可以将一个比较器对象传给TreeSet构造器来告诉树集使用不同的比较方法,此比较器是一个实现Comparator接口的类,此接口声明了一个带有两个参数的方法,此接口的内部实现代码为:

public  interface   Comparator

{

            int  compare(T o1, T o2);

    boolean  equals(Object obj);

}

此接口中的compare方法与compareTo方法一样,如果o1大于o2,则返回负值,如果o1等于o2,则返回0,如果o1小于o2,则返回正值。

如果我们按照姓名对 Student 对象进行排序,则只需要构造这样一个比较器即可,代码如下:

       class  NameComparaTor  implements  ComparaTor

{

       public  int  compare(Student  stu1 , Student  stu2)

{

       Return  stu1.name.comparaTo(stu2.name);

}

}

然后将这个比较器类的对象传给树集

       NameComparaTor  comp=new  NameComparaTor();

       TreeSet  tree=new  TreeSet(comp);

 

这样我们就创建了一个带有比较器的树集,java就可在向这个树集添加元素的时候,自动调用树集本身自带的比较器来查找这个元素所要安放的位置。

因为比较器类我们往往只使用一次,所以它往往被定义为匿名内部类来实现,即上述代码可以简化为:

TreeSet  tree=new  TreeSet(

new  ComparaTor(){

              public  int  compare(Student  stu1 , Student  stu2)

{

              Return  stu1.name.comparaTo(stu2.name);

}

});

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:4628次
    • 积分:160
    • 等级:
    • 排名:千里之外
    • 原创:12篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档