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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 荣天 中级黑马   /  2012-5-30 21:01  /  2082 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. package CollectionDemo;

  2. import java.util.Iterator;
  3. import java.util.TreeSet;
  4. public class CollectionDemo12 {
  5.         public static void main(String[] args) {
  6.                 TreeSet ts=new TreeSet();
  7.                 ts.add(new Student("张三01",18));
  8.                 ts.add(new Student("张三003",15));
  9.                 ts.add(new Student("张三04",22));
  10.                 ts.add(new Student("张三08",21));
  11.                 Iterator it=ts.iterator();
  12.                 while(it.hasNext())
  13.                 {
  14.                         Student stu=(Student)it.next();
  15.                 //        System.out.println(stu.getName()+"===="+stu.getAge());
  16.                 }
  17.         }
  18. }
  19. class Student implements Comparable //Comparable 强制让学生具备比较性
  20. {
  21.         private String name;
  22.         private int age;
  23.         Student(String name,int age)
  24.         {
  25.                 this.name=name;
  26.                 this.age=age;
  27.         }
  28.         public String getName()
  29.         {
  30.                 return name;
  31.         }
  32.         public int getAge()
  33.         {
  34.                 return age;
  35.         }
  36.          //compareTo比较此对象与指定对象的顺序。返回  负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。
  37.         public int compareTo(Object obj)  
  38.         {
  39.                 if(!(obj instanceof Student))
  40.                         throw new RuntimeException("不是学生对象");
  41.                 Student s=(Student)obj;
  42.                 System.out.println(this.name+"--compareTo-"+s.name);
  43.                 if(this.age>s.age)
  44.                         return 1;
  45.                 if(this.age==s.age)
  46.                         return 0;
  47.                 return -1;
  48.         }
  49. }
复制代码
打印的结果:
张三01--compareTo-张三01   //张三01先进来  ……     ??  怎么解释?
张三003--compareTo-张三01   //张三01先进来,张三03进来和张三01比较
张三04--compareTo-张三01     //张三04怎么没和张三03比较呢?
张三08--compareTo-张三01    //张三08怎么也没和张三03比较呢?
张三08--compareTo-张三04

赐教   谢谢

评分

参与人数 1技术分 +1 收起 理由
攻城狮 + 1 赞一个!

查看全部评分

8 个回复

倒序浏览
我这里的运行结果是:
张三003--compareTo-张三01
张三04--compareTo-张三01
张三08--compareTo-张三01
张三08--compareTo-张三04
回复 使用道具 举报
田林 发表于 2012-5-30 22:16
我这里的运行结果是:
张三003--compareTo-张三01
张三04--compareTo-张三01

?   什么情况
回复 使用道具 举报
本帖最后由 Zhang_qian 于 2012-5-31 00:07 编辑

TreeSet的集合底层是二叉树的存储方式,它存储第一个元素("张三01",18)的时候就是在根节点存储该元素,添加第二个元素("张三003",15)时,与第一个元素的年龄进行比较只要比较比第一个小就放在左边,比它大就放在右边,每存一个元素就会先跟根节点的元素比较,然后再重复上面的操作大的放右边小得放左边,取出的时候就是从左边取出也就是排好序后的,所以就得到了你当才输出的那样的结果。
回复 使用道具 举报
本帖最后由 欧阳梦南 于 2012-5-30 23:55 编辑

首先你运行的结果应该是这样的
张三003--compareTo-张三01
张三04--compareTo-张三01
张三08--compareTo-张三01
张三08--compareTo-张三04


这里用到了数据结构的二叉排序树,给你画个图




能看的清吧,二叉排序树特点是,第一个元素是树根,后面的元素都跟树根比较,比树根小的放在树的左孩子上,比树根大的放在树的右孩子上。红色的数字就是元素插入顺序。黑圈里的是对象名和他的年龄。红色1第一个元素没什么说的了,红色2,比张三01小,放在左孩子上,红色3,比树根18岁大,放在右孩子上,此时已经没必要跟张三003比较,因为树根的右孩子一定比左孩子大。红色4,它先跟树根18岁比较,比18大,则到18岁的右孩子上,再接着跟张三04 的22岁比较,比其小 放在张三04的左孩子上,同样没必要跟张三003比较。

排好二叉树就可以根据先序遍历,后序遍历来输出从小到大和从大到小的顺序了。









评分

参与人数 1技术分 +1 收起 理由
攻城狮 + 1 赞一个!

查看全部评分

回复 使用道具 举报
TreeSet 是用二叉树实现排序的, 关于二叉树的详细信息楼主可以百度一下,
这里简单的说一下,第一个元素("张三01",18)进来了,因为没别的对象,就自己和自己比了一下,然后就进来了
第一个元素作为根结点,
第二个元素来了,因为是用age 比较的,15比18小,它被放在了根结点的左边,
第三个元素来了,22比18大,它被放在了根结点的右边,
第四个元素,21比18大,要放在根结点的右边,但是右边已经有个22了,所以再和22比一下,比22小,放在了22的下面左边位置
这样形成了一个树的结构
回复 使用道具 举报
本帖最后由 Zhang_qian 于 2012-5-31 01:46 编辑

刚才又想了一会想到了:TreeSet的集合底层是二叉树的存储方式,它存储第一个元素的时候就是在根节点存储该元素,添加第二个元素时,与第一个进行比较只要比较比第一个小就放在左边,比它大就放在右边,每存一个元素就会先跟根节点的元素比较,然后再重复上面的操作大的放右边小得放左边,取出的时候就是从左边取出也就是排好
回复 使用道具 举报
我的理解.不对之处请指正、
当把一个对象加入TreeSet集合中时,TreeSet调用该对象的compareTo(Object obj)方法与容器中的其他对象比较大小,然后根据红黑树算法决定它的存储位置。如果两个对象通过compareTo(Object obj)比较相等,TreeSet即认为它们存储同一位置。
所以 ts.add(new Student("张三01",18));  就会用 张三01 和 已经存入集合中的 张三01(也就是他自己比一下)。这个是我的猜测= =!

至于下面的比较顺序如上图,第一个元素做为二叉树的树根,小的放在他的左边,大的放在他的右边,因为张三003比张三01小所以放在左边,当张三04进来的时候和张三01比,比01大所以放在右边,不用再和003比,(如果04比01小的话,就放在左边需要跟003再比一次),08进来的时候先和01比,比01大放到右边,然后再和右边的04比,比04小,所以放在04的左边。当读取的时候就按照图示所示,先读左边的树按箭头方向,再读右边的树,按箭头方向。
(希望可以帮到你。PS:楼上几位回的好快…… 我画图的功夫回完了,话说我画的相当丑- -!)
回复 使用道具 举报
首先楼主的结果不对啊
张三003--compareTo-张三01
张三04--compareTo-张三01
张三08--compareTo-张三01
张三08--compareTo-张三04
1,首先进入的是(张三01,18 )由于是第一个进入的没有可比较对象;
2,然后(张三003,15),(张三04,22),(张三08,21)和(张三01,18 )依次比较
3,treeSet的底层是二叉树结构,通过2的比较,已经确定了4个对象的最小年龄对象(张三003,15)和次最小年龄对象(张三01,18 )
4,所以比较器只要再比较一次剩余的两个对象),(张三04,22),(张三08,21)即可;
5,这是由于二叉树的比较排序机制决定的,不会用每个对象后面的每个对象去和前面的每个对象一一去比较,要不就失去了其存在的意义;
我没画图,不知这样楼主能明了不;
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马