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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© L.I.F.E 中级黑马   /  2013-5-28 19:39  /  1628 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 L.I.F.E 于 2013-5-29 07:21 编辑
  1. import java.util.*;
  2. class Person
  3. {
  4.         private String name;
  5.         Person(String name)
  6.         {
  7.                 this.name = name;
  8.         }
  9.         public String getName()
  10.         {
  11.                 return this.name;
  12.         }
  13.         public String toString()
  14.         {
  15.                 return "person:"+name;
  16.         }

  17. }

  18. class Student extends Person
  19. {
  20.         Student(String name)
  21.         {
  22.                 super(name);
  23.         }
  24.         
  25. }

  26. class Worker extends Person
  27. {
  28.         Worker(String name)
  29.         {
  30.                 super(name);
  31.         }
  32. }


  33. class GenericDemo3
  34. {
  35.         public static void main(String[] args)
  36.         {
  37.                 //Student s = new Student();
  38.                 TreeSet<Student> ts = new TreeSet<Student>();
  39.                 ts.add(new Student("lisi01"));
  40.                 ts.add(new Student("lisi02"));
  41.                 ts.add(new Student("lisi03"));

  42.                 Iterator<Student> it = ts.iterator();
  43.                 while (it.hasNext())
  44.                 {
  45.                         System.out.println(it.next().getName());
  46.                 }
  47.                 /*Student s = new Student("lisi001");
  48.                 System.out.println(s.getName());*/


  49.         }
  50. }
复制代码
程序报错,出现类型转换错误,问题出在哪里啊?

评分

参与人数 1技术分 +1 收起 理由
袁梦希 + 1 很给力!

查看全部评分

5 个回复

倒序浏览
TreeSet集合中的元素要具有自然顺序,在这里Student类需要实现Comparable接口;如下:

package test;

import java.util.*;
class Person
{
        private String name;
        Person(String name)
        {
                this.name = name;
        }
        public String getName()
        {
                return this.name;
        }
        public String toString()
        {
                return "person:"+name;
        }

}

class Student extends Person implements Comparable<Student>
{
        Student(String name)
        {
                super(name);
        }

                @Override
                public int compareTo(Student o) {
                        // TODO Auto-generated method stub
                        return this.getName().compareTo(o.getName());
                }
        
}

class Worker extends Person
{
        Worker(String name)
        {
                super(name);
        }
}


class GenericDemo3
{
        public static void main(String[] args)
        {
                //Student s = new Student();
                TreeSet<Student> ts = new TreeSet<Student>();
                ts.add(new Student("lisi01"));
                ts.add(new Student("lisi02"));
                ts.add(new Student("lisi03"));

                Iterator<Student> it = ts.iterator();
                while (it.hasNext())
                {
                        System.out.println(it.next().getName());
                }
                /*Student s = new Student("lisi001");
                System.out.println(s.getName());*/


        }
}

评分

参与人数 1技术分 +1 收起 理由
袁梦希 + 1 很给力!

查看全部评分

回复 使用道具 举报
有两种方式,第一种同楼上的,用comparable
第二种可以用接口comparator比较器接口实现。如下
class GenericDemo3

{

        public static void main(String[] args)

        {

                //Student s = new Student();
                TreeSet<Student> tree = new TreeSet<Student>(new Comparator<Student>(){
                        @Override
                        public int compare(Student o1, Student o2) {
                                // TODO Auto-generated method stub
                                int num = o1.getName().length()-o2.getName().length();
                                int num2=(num==0)?(o1.getAge()-o2.getAge()):num;
                                int  num3=(num2==0)?o1.getName().compareTo(o2.getName()):num2;
                                return num3;
                        }
                });
               
            

                ts.add(new Student("lisi01"));

                ts.add(new Student("lisi02"));

                ts.add(new Student("lisi03"));



                Iterator<Student> it = ts.iterator();

                while (it.hasNext())

                {

                        System.out.println(it.next().getName());

                }

                /*Student s = new Student("lisi001");

                System.out.println(s.getName());*/






            
               



                Iterator<Student> it = ts.iterator();

                while (it.hasNext())

                {

                        System.out.println(it.next().getName());

                }

                /*Student s = new Student("lisi001");

                System.out.println(s.getName());*/





评分

参与人数 1技术分 +1 收起 理由
袁梦希 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
1 先来看看错误
  1. TreeSet<Student> ts = new TreeSet<Student>();
  2.                 ts.add(new Student("lisi01"));
  3.                 ts.add(new Student("lisi02"));//ClassCastException: Student cannot be cast to java.lang.Comparable
  4.                 //ts.add(new Student("lisi03"));
复制代码
类型转换异常:Student 类不能转换为 Compareable
虽然你是在做泛型的测试,但是我们看到错误提示有Compareable。
在看到你定义的是一个TreeSet集合。很明显的是被添加的类没有实现Compareable接口。

2 TreeSet集合
2.1
在使用集合时,我们要注意的是,这个集合的底层数据结构特点,知道它的特点后
才知道这个集合是怎样存放东西的。添加到TreeSet集合中的对象要实现Compareable
接口,原因:实现该接口后,元素才有比较的方式。

2.2
TreeSet底层是红黑树结构(这里就不扩充了),TreeSet集合是怎样添加元素的了?
当把一个对象添加到TreeSet集合中时,TreeSet集合调用被添加对象的compareTo方法
与容器中其他对象比较大小,然后根据红黑树算法决定其存储位置。如果两个对象通过
compareTo比较相等,TreeSet则认为它们因处于同一位置。

2.3  
类型转换异常的解决办法
  1. import java.util.*;
  2. class Person implements Comparable//实现Compareable接口
  3. {
  4.         private String name;
  5.         Person(String name){
  6.                 this.name = name;
  7.         }
  8.         public String getName(){
  9.                 return this.name;
  10.         }
  11.         public String toString(){
  12.                 return "person:"+name;
  13.         }
  14.                 public int compareTo(Object o1){ //必须覆盖compareTo方法
  15.                         return -1;
  16.                 }

  17. }
  18. class Student extends Person{
  19.         Student(String name) {
  20.                 super(name);
  21.         }        
  22. }

  23. class GenericDemo3
  24. {
  25.         public static void main(String[] args)  {
  26.                 TreeSet<Student> ts = new TreeSet<Student>();
  27.                 ts.add(new Student("lisi01"));
  28.                 ts.add(new Student("lisi02"));
  29.                 ts.add(new Student("lisi03"));

  30.                                 Comparator com = ts.comparator();
  31.                                 System.out.println(com);//返回对象所用的比较器

  32.                 Iterator<Student> it = ts.iterator();//返回迭代器
  33.                 while (it.hasNext()) {
  34.                         System.out.println(it.next().getName());//迭代集合元素
  35.                 }
  36.         }
  37. }
复制代码
解决方案是实现Compareable接口,实现compareTo方法。
但是这里要注意的是:
  没有实现compareable接口时,怎么还是能添加一个元素 new Student("lisi01")?
原因很简单:
add 方法详解:
将指定的元素添加到此 set(如果该元素尚未存在于 set 中)。更确切地讲,如果该 set 不包含满足 (e==null ? e2==null : e.equals(e2)) 的元素 e2,则将指定元素 e 添加到此 set 中。如果此 set 已经包含这样的元素,则该调用不改变此 set 并返回 false。
因为刚开始的集合为空,添加第一个元素时,元素e2 为空引用,所以能添加进集合中。当再次添加时,add(new Student("lisi02")),调用完对象的equals方法后,会接着调用对象的compareTo方法决定第二个元素的位置。由于没有实现compareable接口,自然会出现上述类型转换异常。

希望能帮到你
TreeSet集合没有写的很详细,很多细节性的东西楼主还需自己体会。
这里只分析了出错的原因。



评分

参与人数 1技术分 +2 收起 理由
袁梦希 + 2 很给力!

查看全部评分

回复 使用道具 举报
你就记住TreeSet集合在使用自定义对象的事情是需要对compareable和cimpareator接口进行重写的,不然它无法进行判断
回复 使用道具 举报
哦,明白了!由于TreeSet自然顺序,而new Student(“lisi001”)这里不具备可比性!所以要么实现comparable接口,要么写comparator比较器来实现
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马