关于在TreeSet中添加自定义类 报ClassCastException的解决方法

 一、先来看一下TreeSet的继承结构和类声明形式

继承结构:

java.lang.Object 
   |_ java.util.AbstractCollection<E> 
        |_ java.util.AbstractSet<E> 
              |_ java.util.TreeSet<E> 

类声明:
public class TreeSet<E> 
    extends AbstractSet<E> 
    implements SortedSet<E>, Cloneable, java.io.Serializable //它实现了sortedSet,有排序的功能

 

二、TreeSet的主要性质


1、TreeSet中不能有重复的元素;

2、TreeSet具有排序功能;

3、TreeSet中的元素必须实现Comparable接口并重写compareTo()方法,TreeSet判断元素是否重复、以及确定元素的顺序靠的都是这个方法;(这条性质比较重要,如果读者对TreeSet内部机制比较熟悉的话这条性质应该不难理解;如果读者不太理解的话可以参看以下这篇文章http://wlh269.javaeye.com/blog/376430)

4、对于java类库中定义的类,TreeSet可以直接对其进行存储,如String,Integer等(因为这些类已经实现了Comparable接口);

5、对于自定义类,如果不做适当的处理,TreeSet中只能存储一个该类型的对象实例,请看程序示例:

import java.util.*;
public class TreeSetDemo{
 public static void main(String args[]){
  TreeSet<Demo> tSet=new TreeSet<Demo>();
  Demo d1=new Demo(1,"abc");
  Demo d2=new Demo(2,"xyz");
    
  tSet.add(d1);
  tSet.add(d2);//如果有这条语句,运行程序时会抛出ClassCastException异常
                       //如果没有这条语句,程序会正常运行,并输出d1的内容
  Iterator itr=tSet.iterator();
  while(itr.hasNext()){
   Demo d=(Demo)itr.next();
   System.out.print(d.a+" "+d.b);
   System.out.println();
  }
 } 
}
class Demo{
 int a;
 String b;
 public Demo(int a,String b){
  this.a=a;
  this.b=b;
 }
}

三、在TreeSet中存储自定义类的实现方法

示例:

import java.util.*;
public class TreeSetDemo{
 public static void main(String args[]){
  TreeSet<Demo> tSet=new TreeSet<Demo>();
  Demo d2=new Demo(2,"xyz");
  Demo d3=new Demo(2,"uvw");

  Demo d1=new Demo(1,"abc");
  
  tSet.add(d1);
  tSet.add(d2);
  tSet.add(d3);


  Iterator itr=tSet.iterator();
  while(itr.hasNext()){
   Demo d=(Demo)itr.next();
   System.out.print(d.a+" "+d.b);//注意此程序运行时会输出几个元素
   System.out.println();
  }
 } 
}
class Demo implements Comparable{
 int a;
 String b;
 public Demo(int a,String b){
  this.a=a;
  this.b=b;
 }
  public int compareTo(Object o){
   Demo demo=(Demo)o;
  if(this.a>demo.a){
   return 1;
  }else if(this.a<demo.a){
   return -1;
  }else{
   return 0;
  }
 }
}

解析:上面程序会输出两个元素,并且是以a为判断标准按序输出的。当调用TreeSet的add()方法时,在TreeSet的内部会间接调用Demo的compareTo()方法、然后和TreeSet中已经存在的其他元素一一进行比较,在比较的过程中完成“判断是否重复”以及“排序”的功能:当在某次比较的过程中发现compareTo()返回0,就会认为待加入的元素已经存在于TreeSet中,返回-1或1的话就会根据TreeSet默认的比较器进行排序。

 

下面对程序进行修改,重写compareTo()方法,让TreeSet以a和b两个属性为依据来判断元素是否重复以及元素的顺序,请看下面的示例:

import java.util.*;
public class TreeSetDemo{
 public static void main(String args[]){
  TreeSet<Demo> tSet=new TreeSet<Demo>();
  Demo d1=new Demo(1,"abc");
  Demo d2=new Demo(2,"xyz");
  Demo d3=new Demo(2,"uvw");
  
  tSet.add(d1);
  tSet.add(d2);
  tSet.add(d3);
  
  Iterator itr=tSet.iterator();
  while(itr.hasNext()){
   Demo d=(Demo)itr.next();
   System.out.print(d.a+" "+d.b);//注意这次输出的元素个数
   System.out.println();
  }
 } 
}
class Demo implements Comparable{
 int a;
 String b;
 public Demo(int a,String b){
  this.a=a;
  this.b=b;
 }
  public int compareTo(Object o){
   Demo demo=(Demo)o;
   if(this.a==demo.a&&this.b.equals(demo.b)){
   return 0;
  }else if(this.a>demo.a){
   return 1;
  }else {
   return -1;
  }
 }
}

解析:这次改动了compareTo()方法,程序输出了三个元素d1,d2和d3;当我们自己定义类,并且需要将自定义的类存到TreeSet中的时候,需要认真考虑compareTo的定义方式即需要认真考虑实际应用中依据什么判断元素是否重复和元素的顺序。


转载自lubiaopanlubiaopan的csdn博客  测试通过程序没有问题 这里表示感谢

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值