A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© ぺsimon☆ 中级黑马   /  2013-4-25 15:05  /  2322 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. /*
  2. 这是关于TreeSet的功能演示.


  3. 需求:向TreeSet集合存入Student学生对象,并按照年龄进行排序
  4. */

  5. import java.util.*;

  6. class Student implements Comparable  //创建学生类并实现Comparable类
  7. {
  8.         private String name;
  9.         private int age;
  10.         Student(String name,int age) //构造函数初始化
  11.         {
  12.         this.name=name;
  13.         this.age=age;
  14.         }
  15.         public String getName() //定义获取姓名的函数
  16.         {
  17.         return this.name;
  18.         }
  19.         public int getAge() //定义获取年龄的函数
  20.         {
  21.         return this.age;
  22.         }

  23.         public void setName(String name)  //定义改变姓名的函数
  24.         {
  25.         this.name=name;
  26.         }
  27.         public void setAge(int age) //定义改变年龄的函数
  28.         {
  29.         this.age=age;
  30.         }
  31.         public int compareTo(Object obj)  //复写compareTo方法
  32.         {
  33.         if(!(obj instanceof Student))
  34.         throw new RuntimeException(); //抛出RuntimeException异常
  35.         Student s=(Student)obj;
  36.         System.out.println(this.name+"...compareTO..."+s.name);
  37.         if(this.age>s.age)
  38.         {
  39.         return 1;
  40.         }
  41.         if(this.age==s.age)
  42.         {
  43.         return this.name.compareTo(s.name);
  44.         }

  45.         return -1;
  46.         }
  47. }
  48. class TreeSetDemo
  49. {
  50.         public static void main(String[] args)
  51.         {
  52.         TreeSet ts=new TreeSet();  //创建容器
  53.         ts.add(new Student("xiaochen01",31));
  54.         ts.add(new Student("xiaochen01",31));
  55.         ts.add(new Student("xiaochen02",32));
  56.         ts.add(new Student("xiaochen03",33));
  57.         ts.add(new Student("xiaochen04",34));
  58.         ts.add(new Student("xiaochen05",30));
  59.         ts.add(new Student("xiaochen06",30));
  60.        
  61.         Iterator it=ts.iterator();  //获取迭代器
  62.         //遍历并输出容器中的数据
  63.         while(it.hasNext())  
  64.         {
  65.         Student s=(Student)it.next();

  66.         sop(s.getName()+"......"+s.getAge());  
  67.         }
  68.         }

  69.         public static void sop(Object obj)
  70.         {
  71.         System.out.println(obj);
  72.         }
  73. }
复制代码
问题1:为什么要实现Coparrable类呢?现在自己写的compareTo方法已经可以比较两个数的大小了
问题2:
运行结果如下: 为什么xiaochen04进来之后不用跟xiaochen01比较大小呢?
xiaochen01...compareTO...xiaochen01
xiaochen02...compareTO...xiaochen01
xiaochen03...compareTO...xiaochen01
xiaochen03...compareTO...xiaochen02
xiaochen04...compareTO...xiaochen02
xiaochen04...compareTO...xiaochen03
xiaochen05...compareTO...xiaochen02
xiaochen05...compareTO...xiaochen01
xiaochen06...compareTO...xiaochen02
xiaochen06...compareTO...xiaochen01
xiaochen06...compareTO...xiaochen05
xiaochen05......30
xiaochen06......30
xiaochen01......31
xiaochen02......32
xiaochen03......33
xiaochen04......34

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

5 个回复

倒序浏览
楼主你好,这是我自己的总结,你可以看看!

TreeSet第一种排序方式:
往TreeSet集合里面存对象,并没有把排序的方式告诉集合
,所以往TreeSet集合里存的对象必须具备比较性。
实现Comparable接口,实现整体排序,这种排序被称为类的

自然排序.类的CompareTo方法被称为自然比较方法.
在比较的时候,第一先数据先进来,然后第二个再进来,第二
个数据调用自己的CompareTo方法与第一先进来的数据进行
比较,
返回int类型,返回0,此类对象与指定对象相等,所以不存

比如Student对象中,只有年龄相同就不存了,那么就错了

,年龄相同之后还要判断名字相同,都相同以后才视为同一
个人,所以不存。也就是说:当主要条件相等时,要对次要
条件进行排序。
如果按对象的降序排列(盲点)

因为name是字符串类型,所以查找String对应的API中有对
应的compareTo方法,用他来对name进行排序也就是String
类已经实现了Comparable接口了。是按字典顺序排序

为了效率,TreeSet底层利用二叉树原理。
也就是说返回负数往左边放,正数放在右边,0不存的原理
减少比较次数就提高了效率。左中右的方式取出数据.

如果想往TreeSet集合里怎么存的就怎么取出来,怎么办?
只要在compareTo方法中返回1,并且以二叉树的顺序取出。
保证元素唯一性的依据是compareTo返回0.
====================================================
TreeSet第二种排序方式:

当元素自身不具备比较性时,或者具备的比较性不是所需要
的,这时就需要让集合自身具备比较性。
我举个例子:比如说,可以拿集合作为参照物,拿两个元素

跟这个参照物进行比较,如果比这个物体小就放左,比这个
物体大就放右面。就好比一个刻度板。
集合一初始化就有比较方式,参与构造函数。
而第一种方式是拿Student对象中的元素来一个比较一个,
来一个比较一个。
在Student对象中,如果想按照姓名排序,就不能改代码了
。那么怎么实现呢。
首先,实现Comparator接口,然后重写compare,传两个参

数进行比较,不用重新ecquls()方法了,因为实现类已经重
写了。
当两种排序都存在时,以比较器为主。


回复 使用道具 举报
你不实现 Comparable接口,能有compareTo方法吗。实现一个接口,必须要实现接口中的方法。
你的Student实现了 Comparable接口。就必须重写compareTo方法,在这个方法中根据Student特有的属性age来比较。如果你不实现Comparable,自己在Student中定义compareTo方法是没有任何意义的。

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
第二个问题。2先和1比较了,2比1大,4再和2比较,4比2也大,4根本就不需要和1比较了
回复 使用道具 举报
估计跟TreeSet的底层数据结构有关。。。
二叉树的结果是节点左边小于节点节点右边大于节点
当你进行比较的时候。。。
第一次跟根节点比较如果相同则停止比较..
如果小于根节点就去左子树进行比较,则不比较右子树的所有节点。否则相反。
如果当前节点的值小于要比较的对象,并且左子树为null,那么则把要比较的对象放在当前节点的左子树上,并结束;
如果当前节点的值大于要比较的对象,并且右子树为null,那么则把要比较的对象放在当前节点的右子树上,并结束;
一层一层的递归比较。。。

我感觉是这样的。。
这样做很节省时间平均只要话费log(n)次的查找就能却确定位置

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
如果仍有问题,请继续追问,如果问题已解决,请将分类改为已解决,谢谢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马