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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 天凌蓝 于 2014-3-4 13:13 编辑

我发现JDK1.7的TreeSet好像有点问题,不知道是不是真的。我试了好几次,程序运行老是异常。
我用一个对象放进TreeSet里面,还会报这个异常Exception in thread "main" java.lang.ClassCastException: Student cannot be cast to java.lang.Comparable

而且实现了Comparable接口后运行结果还有点问题,请各位大神帮我看一下,谢谢了
  1. import java.util.*;

  2. class  TreeSetDemo2
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                 TreeSet ts=new TreeSet();
  7.                
  8.                 ts.add(new Student("lisi02",22));        
  9.                 //ts.add(new Student("lisi07",20));
  10.                 //ts.add(new Student("lisi09",19));
  11.                 //ts.add(new Student("lisi01",40));
  12.                
  13.                 Iterator it=ts.iterator();

  14.                 while (it.hasNext())
  15.                 {
  16.                         Student stu=(Student)it.next();
  17.                         sop(stu.getName()+"..."+stu.getAge());
  18.                 }
  19.                 /*
  20.                 for(Iterator it=ts.iterator();it.hasNext();)
  21.                 {
  22.                         Student stu=(Student)it.next();
  23.                         sop(stu.getName()+"..."+stu.getAge());
  24.                 }*/
  25.         }
  26.         public static void sop(Object obj)
  27.         {
  28.                 System.out.println(obj);
  29.         }
  30. }
  31. class Student implements Comparable//该接口强制让学生具备比较性。
  32. {
  33.         private String name;
  34.         private int age;

  35.         Student(String name,int age)
  36.         {
  37.                 this.name=name;
  38.                 this.age=age;
  39.         }

  40.         public int compareTo(Object obj)
  41.         {
  42.                 if(!(obj instanceof Student))
  43.                         throw new RuntimeException("不是学生对象");
  44.                
  45.                 Student s=(Student)obj;

  46.                 System.out.println(this.name+"...compareto..."+s.name);

  47.                 if(this.age>s.age)
  48.                         return 1;
  49.                 if(this.age==s.age)
  50.                         return 0;
  51.                 return -1;
  52.         }

  53.         public String getName()
  54.         {
  55.                 return name;
  56.         }
  57.         public int getAge()
  58.         {
  59.                 return age;
  60.         }
  61. }
复制代码
单个ts.add(new Student("lisi02",22));        运行时,不实现接口会发生异常,而且实现接口后发现会跟自己比较。多个的也会跟自己比较一次。



单个.jpg (9.54 KB, 下载次数: 22)

单个的

单个的

多个.jpg (19.77 KB, 下载次数: 21)

多个的

多个的

评分

参与人数 1技术分 +1 收起 理由
zzkang0206 + 1

查看全部评分

8 个回复

倒序浏览
TreeSet实际上一棵红黑树,红黑树是一颗近似平衡树,你可以看下红黑树的定义(http://blog.csdn.net/eric491179912/article/details/6179908),
我现在手边没有写好的红黑树,所以给你找了个链接(http://blog.chinaunix.net/uid-26548237-id-3479434.html),
PS:    如果看不懂的话不要紧,红黑树算是算法里比较麻烦的,只要明白理论就好,以后熟了再写代码

评分

参与人数 1技术分 +1 收起 理由
zzkang0206 + 1

查看全部评分

回复 使用道具 举报
我用了 1.7 跑了下没有出现问题

lisi02...compareto...lisi02
lisi07...compareto...lisi02
lisi09...compareto...lisi02
lisi09...compareto...lisi07
lisi01...compareto...lisi07
lisi01...compareto...lisi02
lisi09...19
lisi07...20
lisi02...22
lisi01...40
回复 使用道具 举报
榨菜 发表于 2014-3-3 23:17
我用了 1.7 跑了下没有出现问题

lisi02...compareto...lisi02

你单个运行呢?会不会跟我单个运行一样?
回复 使用道具 举报
榨菜 发表于 2014-3-3 23:17
我用了 1.7 跑了下没有出现问题

lisi02...compareto...lisi02

单个元素,JDK1.6运行后是这样的:
lisi02...22

而JDK1.7运行后是:
lisi02...compareto...lisi02
lisi02...22

还有,你说你的答案没出现问题,为什么你的答案也出现了:
lisi02...compareto...lisi02
亲,你有没有试着注释掉实现接口去运行单个元素呢?看看你的JDK1.7单个元素并没有实现接口时,会不会也抛出异常呢?
回复 使用道具 举报
Amorvos 发表于 2014-3-3 23:10
TreeSet实际上一棵红黑树,红黑树是一颗近似平衡树,你可以看下红黑树的定义(http://blog.csdn.net/eric491 ...

谢谢!!!
回复 使用道具 举报
天凌蓝 发表于 2014-3-3 23:35
单个元素,JDK1.6运行后是这样的:
lisi02...22

注释掉后 运行单个的也会出现异常 Exception in thread "main" java.lang.ClassCastException: com.itheima.Student cannot be cast to java.lang.Comparable
回复 使用道具 举报
天凌蓝 发表于 2014-3-3 23:35
单个元素,JDK1.6运行后是这样的:
lisi02...22

我看了下源码 TreeSet里面其实是调用的是TreeMap  TreeMap里面需要用到比较器。里面有个获得比较器的方法   k1就是传进去的Student对象.  然后(Comparable<? super K>)k1)  就相当于获得Comparable的对象。 因为没有继承Comparable,所以得不到对象,所以会出现类型转换出现异常(多态的原理,我说不清)。--水平低只能说到这里了。
    final int compare(Object k1, Object k2) {
        return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
            : comparator.compare((K)k1, (K)k2);
    }

评分

参与人数 1技术分 +1 收起 理由
zzkang0206 + 1

查看全部评分

回复 使用道具 举报
问题我已经差不多知道了。

1、其实代码是没有问题的。

2、单个元素存放进TreeSet里面,
     当  不实现Comparable接口覆写compareTo方法时,在  JDK1.6版本 这种情况是不会报错的。  反而在JDK1.7版本里面  就会发生异常。
    当  实现Comparable接口覆写compareTo方法时,在  JDK1.6版本 这种情况是不会打印出自己跟自己比较的。  反而在JDK1.7版本里面  就会打印出自己跟自己比较。

3、多个元素放进TreeSet里面,在 JDK1.6 版本  不会多出现一次自己跟自己比较 ; 而在 JDK1.7 版本  会多出现一次自己跟自己比较。

以上所述:
       得出了一个结论就是 这个问题可能是JDK本身问题,1.7版本对1.6版本进行了升级, 让TreeSet中存在单个元素时,不管是一个元素而且没有实现接口覆写compareTo方法(1.6版本不会提示异常),就会出现异常提示,说明JDK1.7版本提高了安全性 , 让当一个元素存在TreeSet时,也要进行跟自己比较一次。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马