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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 魏志雷 黑马帝   /  2012-1-27 22:57  /  2170 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 魏志雷 于 2012-2-1 14:16 编辑

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

                ts.add(new Student("java02", 22));
                // ts.add(new Student("java02",20));
                // ts.add(new Student("java03",19));
                // ts.add(new Student("java04",40));

                Iterator it = ts.iterator();

                while (it.hasNext())
                {
                        Student stu=(Student)it.next();
                        sop(stu.getName()+"::"+stu.getAge());
                }
        }

        public static void sop(Object obj)
        {
                System.out.println(obj);
        }
}

class Student
{
        private String name;
        private int age;

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

        public String getName()
        {
                return name;
        }

        public int getAge()
        {
                return age;
        }
}
这段代码为什么会抛出ClassCastException异常,视频上面讲解,存储一个对象是不会抛出异常的,检查好几遍没有发现什么原因!

4 个回复

倒序浏览
我将代码复制,运行,无异常,可运行。是否有两个Student 类,以至出错?

评分

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

查看全部评分

回复 使用道具 举报
本帖最后由 逄焕玮 于 2012-1-28 15:20 编辑

TreeSet类是需要对存入Set集合中的元素进行排序的,也就是说一个类需要实现Comparable接口,重写compareTo()方法,让该类对象具备了比较性,才能存入TreeSet的,往TreeSet里添加不具备比较性的元素,是会报ClassCastException的
上述示例中 class Student 可改写如下
  1. class Student implements Comparable<Student> {
  2.         private String name;
  3.         private int age;

  4.         Student(String name, int age) {
  5.                 this.name = name;
  6.                 this.age = age;
  7.         }

  8.         public String getName() {
  9.                 return name;
  10.         }

  11.         public int getAge() {
  12.                 return age;
  13.         }

  14.         // 默认排序方式为学生姓名的自然顺序,即字典顺序
  15.         // 若姓名相同,则按年龄由小到大排列
  16.         // 对于姓名年龄均相同的,认为是同一个人,存不进去
  17.         public int compareTo(Student stu) {
  18.                 // 方法内部调用的这俩compareTo是String类实现Comparable接口,重写的方法
  19.                 // int compareTo(String anotherString) 按字典顺序比较两个字符串,详见API文档 java.lang.String类
  20.                 if (this.name.compareTo(stu.name) > 0)
  21.                         return 1;
  22.                 if (this.name.compareTo(stu.name) == 0)
  23.                         return this.age - stu.age;  // 姓名相同时,比较年龄
  24.                 return -1;
  25.         }
  26. }
复制代码
上述为TreeSet的第一种排序方式:
让存入TreeSet的元素具备比较性,也就是需要让元素对应的类实现Comparable接口,覆盖compareTo方法,该方式也称为元素的自然顺序,或者默认顺序

TreeSet还有第二种排序方式:
当元素自身不具备比较性时,或者其拥有的比较性并不是我们所需要的,这时就需要让容器自身具备比较性
通过构造方法  TreeSet(Comparator<? super E> comparator)  构造一个新的空 TreeSet,它根据指定的比较器Comparator进行排序。
需要自建一个比较器,implements Comparator,实现其int compare(T o1, T o2) 方法
  1. class MyComparator implements Comparator<Student> {

  2.         public int compare(Student s1, Student s2) {
  3.                 int num = s1.getName().compareTo(s2.getName());
  4.                 if (num == 0)
  5.                         return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
  6.                   //int的包装类Integer也有compareTo方法的
  7.                 return num;
  8.         }
  9. }
复制代码
TreeSet<Student> ts = new TreeSet<Student>(new MyComparator());
new一个比较器对象,作为参数传递给TreeSet的构造方法

当两种方式共存时,以Comparator为主,Comparable为次
回复 使用道具 举报
本帖最后由 黄秋 于 2012-1-28 14:42 编辑

原来是加入第二个元素时有异常。LS已说得详细,TreeSet是有序的,要实现Comparable接口,重写compareTo()方法。如不需有序,可用ArrayList 代替 TreeSet。如果Student 只有两个属性,可用TreeMap :
  1. import java.util.*;
  2. public class TreeSetDemo{
  3.         public static void main(String[] args)
  4.         {
  5.                 TreeMap tm = new TreeMap();
  6.                 tm.put("java02", 22);
  7.                 tm.put("java02",20);
  8.                 tm.put("java03",19);               
  9.                 System.out.println(tm);               
  10.         }
  11. }
复制代码
回复 使用道具 举报
本帖最后由 魏志雷 于 2012-1-30 16:20 编辑

我晕死了,这段代码和老师的一样,我的运行会出错,虽然你们说的正确,但是已经把代码改变了,现在我也找到问题所在了,终于发现我和老师不同的地方,老师用的是JDK1.6,我用的JDK1.7换成1.6之后就不会出错了,幸好我看到泛型也出错了,提示让我改成JDK1.6,没想到改成JDK1.6之后这段代码也不会提示错误了,呵呵,蒙对了!

评分

参与人数 1技术分 +1 收起 理由
admin + 1 问题已解决,建议把标题修改成已解决!.

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马