问题描述
- Java TreeSet插入对象疑问
-
首先是Customer类定义:package com.lzw; import java.util.Comparator; public class Customer implements Comparator<Object>{ private long id private String name; public Customer(String name,long id){ this.id=id; this.name=name; } public int compare(Object o1,Object o2){ Customer c1=(Customer)o1; Customer c2=(Customer)o2; if(c1.getName().compareTo(c2.getName())>0) return -1; if(c1.getName().compareTo(c2.getName())<0) return 1; return 0; } public String getName(){ return name; } public long getId(){ return this.id; } }
然后是CustomerComparator类定义:
package com.lzw; import com.lzw.Customer; import java.util.Comparator; import java.util.Set; import java.util.TreeSet; import java.util.Iterator; public class CustomerComparator implements Comparator<Object>{ public int compare(Object o1,Object o2){ Customer c1=(Customer)o1; Customer c2=(Customer)o2; if(c1.getName().compareTo(c2.getName())>0) return -1; if(c1.getName().compareTo(c2.getName()) return 0; } public static void main(String[] args) { // TODO 自动生成的方法存根 TreeSet<Customer> set=new TreeSet<Customer>(new CustomerComparator()); Customer c1=new Customer("Andy",109201041); Customer c2=new Customer("JACK",109207042); Customer c3=new Customer("MIKE",109207043); Customer c4=new Customer("Kath",109207044); set.add(c1); set.add(c2); set.add(c3); set.add(c4); Iterator it=set.iterator(); while(it.hasNext()) { Customer customer=(Customer)it.next(); System.out.println(customer.getName()+" "+customer.getId()); } } }
实例化对象:
TreeSet<Customer> set=new TreeSet<Customer>(new CustomerComparator());
如果改成:
TreeSet<customer> set=new TreeSet<customer>();
在 set.add(c1);语句时报错误:
Exception in thread "main" java.lang.ClassCastException: com.lzw.Customer cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1290)
at java.util.TreeMap.put(TreeMap.java:538)
at java.util.TreeSet.add(TreeSet.java:255)
at com.lzw.CustomerComparator.main(CustomerComparator.java:24)
问题:1、请问为什么会这样?2、TreeSet的集合元素是Customer对象,我也在Customer类实现了compare的方法,为什么在add的时候不是调用这个方法而是在CustomerComparator实现的compare的方法?
解决方案
treeset这个类,两种方式初始化,有指定比较器 和 没有指定比较器。
查看treeset这个类,父类是treemap,在执行add方法时,其实就是treemap的add。
源码要求,要么传一个comparator比较器给treeset;要么不传比较器时,要求元素类要实现comparable接口。
注:区分
Comparator 比较器的比较方法为 compare
Comparable 的比较方法为compareTo
解决方案二:
public class Customer implements Comparator
改成
public class Customer implements Comparable
如果treeset中通过构造初始化的,Comparator。
如果构造函数没有初始化Comparator,那么add进入的对象必须实现Comparable才行,不然无法转化对象。
解决方案三:
都写着class cast exception了
java.lang.ClassCastException: com.lzw.Customer cannot be cast to java.lang.Comparable
強转出错,新手错误啊