黑马程序员技术交流社区

标题: 一个compareTo的问题 [打印本页]

作者: hdsjsql    时间: 2013-4-24 11:17
标题: 一个compareTo的问题
本帖最后由 hdsjsql 于 2013-4-24 11:18 编辑

在毕老师视频15-02中向TreeSet中传人第二个对象时,才会调用compareTo方法,
为什么运行时,添加第一个对象时,就调用了compareTo方法,用于自己与自己比较

class TreeSetDemo
{
        public static void main(String[] args)
        {
                TreeSet ts = new TreeSet();

                ts.add(new Student("lisi02",22));
                ts.add(new Student("lisi007",20));
                ts.add(new Student("lisi09",19));
                ts.add(new Student("lisi08",19));
                //ts.add(new Student("lisi007",20));
                //ts.add(new Student("lisi01",40));

                Iterator it = ts.iterator();
                while(it.hasNext())
                {
                        Student stu = (Student)it.next();
                        System.out.println(stu.getName()+"..."+stu.getAge());
                }
        }
}


class Student implements Comparable//该接口强制让学生具备比较性。
{
        private String name;
        private int age;

        Student(String name,int age)
        {
                this.name = name;
                this.age = age;
        }

        public int compareTo(Object obj)//在毕老师的视频15-02中,此方法应该在传入的二个对象时才调用此方法,
                                        //为什么运行时,第一次就调用了
        {

                //return 0;
               
                if(!(obj instanceof Student))
                        throw new RuntimeException("不是学生对象");
                Student s = (Student)obj;

                System.out.println(this.name+"....compareto....."+s.name);
                if(this.age>s.age)
                        return 1;
                if(this.age==s.age)
                {
                        return this.name.compareTo(s.name);
                }
                return -1;
                /**/
        }

        public String getName()
        {
                return name;

        }
        public int getAge()
        {
                return age;
        }
}

0.png (5.01 KB, 下载次数: 13)

0.png

作者: wangyougu010    时间: 2013-4-24 11:41
不会的,你这个程序一点错都没有,我贴了一个截图,运行结果的,你仔细看看,第一个比较是你添加的第二个元素,也就是007.

无标题.png (8.66 KB, 下载次数: 20)

无标题.png

作者: hdsjsql    时间: 2013-4-24 11:52
wangyougu010 发表于 2013-4-24 11:41
不会的,你这个程序一点错都没有,我贴了一个截图,运行结果的,你仔细看看,第一个比较是你添加的第二个元素,也 ...

我也运行了几篇,每次都是第一个对象去调用。实在不解
作者: 聖手`书生    时间: 2013-4-24 13:04
这个程序,我也运行了一下,运行结果也是 lis02和自己比了一下,是和毕老师打印结果不一样。我也不太理解……
作者: 张洪慊    时间: 2013-4-24 13:07
本帖最后由 张洪慊 于 2013-4-24 13:11 编辑

我在写这个程序时候也遇到了,我当时也在想
因此我去翻看了源码:
我的是JDK 1.7
  1. /*
  2. 以下摘了部分源码:
  3. 你要知道TreeSet底层用的是TreeMap,TreeSet集合中的对象是作为TreeMap的Key.
  4. */
  5. final int compare(Object k1, Object k2) {
  6.         return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
  7.             : comparator.compare((K)k1, (K)k2);
  8.     }
  9. public V put(K key, V value) {
  10.         Entry<K,V> t = root;
  11.         if (t == null) {
  12.             compare(key, key); // type (and possibly null) check
  13.           /*
  14.          compare(key,key):这个就是说明问题的关键
  15.         它首先把第一个元素自身和自身比了下
  16.         源代码注释说:类型检测(可能为null)
  17.        个人理解:它是为了判断第一个元素是否具有可比性(自然顺序/指定比较器)
  18.        如果不具备,那么不好意思,下面的元素我也没必要比了.
  19.         */
  20.             root = new Entry<>(key, value, null);
  21.             size = 1;
  22.             modCount++;//验证是否发生并发修改异常
  23.             return null;
  24.         }
复制代码
/*
至于毕老师的运行结果
可能是JDK版本不同,
底层源代码实现略有差别.
*/
作者: Miss小强    时间: 2013-4-24 13:31
  1. lisi007....compareto.....lisi02
  2. lisi09....compareto.....lisi02
  3. lisi09....compareto.....lisi007
  4. lisi08....compareto.....lisi007
  5. lisi08....compareto.....lisi09
  6. lisi08...19
  7. lisi09...19
  8. lisi007...20
  9. lisi02...22
复制代码
我的结果是这样的,应该没问题啊;
我觉得你是不是添加了两次lisi2啊;
按道理来说是不会出现那种情况的;如果是自己和自己比就不符合逻辑了
是想进去的和已经进去的比,里面都没有就不存在比较的必要了;
作者: hdsjsql    时间: 2013-4-24 13:59
张洪慊 发表于 2013-4-24 13:07
我在写这个程序时候也遇到了,我当时也在想
因此我去翻看了源码:
我的是JDK 1.7/*

我也认为是版本的问题
作者: 黄玉昆    时间: 2013-4-24 22:34
如果问题解决了,请将问题分类改为“已解决”,谢谢
作者: 袁梦希    时间: 2013-4-24 22:51
应该和版本没多大关系,楼主你用的是什么版本的jdk?
作者: hdsjsql    时间: 2013-4-27 21:02
袁梦希 发表于 2013-4-24 22:51
应该和版本没多大关系,楼主你用的是什么版本的jdk?

我用的1.7.0_21




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2