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

原创 2013年12月05日 20:06:16

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);

}

});

相关文章推荐

TreeSet方法之一当向TreeSet中添加Person对象 情况一

package andycpp; public class Person { private String name; private Integer age; //get set 方法 p...

java之TreeSet里添加自定义对象

以一个例子来说明: package javastudy; import java.util.Comparator; import java.util.Iterator; import ...

TreeSet方法之一 向TreeSet中添加的元素

package andycpp; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; import...

TreeSet()原理及使用

1、TreeSet()是使用二叉树的原理对新add()的对象按照指定的顺序排序(升序、降序),每增加一个对象都会进行排序,将对象插入的二叉树指定的位置。 2、Integer和String对象都可以进行...

TreeSet保证元素唯一并实现排序的原理

TreeSet:根据构造方法的不用,选择使用自然排序或者比较器排序。 按照实际的需求,可以对元素进行排序。并且保证唯一。 怎么保证的呢? 排序:底层结构是二叉树。按...

TreeSet实现原理

前言        首先明白TreeSet属于集的范围,所以它只能存放引用类型,不能用于基本数据类型,实现了set接口,所以它本身不能有重复的元素,当存入自定义的引用类型的时候就必须考虑到元素不可重...

多进程、多线程、多核CPU——(I)

前言 在介绍多线程时,首先分析进程、以及多道程序设计模型。进程是操作系统中最重要的抽象概念之一,使得在即使只有一个CPU的机器上,也支持(伪)并发,即将一个单独的CPU变成多个虚拟的CPU。 多到...
  • Wel_qin
  • Wel_qin
  • 2014年05月02日 16:23
  • 50530

Java强制类型转换--object对象转换为String的一些总结

Java强制类型转换

黑马程序员——集合的特殊功能之TreeSet集合如何保证元素的唯一及排序的

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- TreeSet集合储存的元素特点是唯一和自动排序,它是如何实现的呢? class Tre...
  • DoSamba
  • DoSamba
  • 2015年12月29日 02:33
  • 989

黑马程序员------TreeSet集合框架存储自定义元素之排序Comparable与Comparator

------- android培训、java培训、期待与您交流! ---------- TreeSet集合框架存储自定义元素之排序Comparable与Comparator 我们知道,往TreeSe...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:黑马程序员——TreeSet集合添加元素的原理
举报原因:
原因补充:

(最多只允许输入30个字)