游戏Java

« Previous day (十二月 10, 2005) | Main | Next day (十二月 12, 2005) »

http://blog.matrix.org.cn/Kaizen/date/20051211 星期日 2005年12月11日

Comparable问题

code的时候发现了这样一个问题,很细小但是却值得重视。问题是发生在实现compareTo的时候,规则我还是比较清楚,自反性,对称性,传递性和非空性,不过缺漏了一点!我写一个class,并在将其产生的n个Instance add到一个TreeSet后却发现这个TreeSet里面只有一个Instance!但是将TreeSet换成HashSet后,n个Instance全都添加进去了,why?解释只有一个,在TreeSet和HashSet里面比较对象所使用的方法是不一样的。
后面我又在Effective Java上面找到了答案——“有序集合使用了由compareTo方法而不是equlas方法施加的相等测试”,上面虽然说了这样的情况不会出现灾难性的后果,但是我想尽量避免出现这样的情况是必要的。
不知道有没有人也遇到过这个问题,却还不清楚到底怎么回事或是根本没有发现,希望下面的例子大家看了后有点收获;
                                                             CODE                                                                          
import java.util.*;

class ComMem implements Comparable
{
 int id;
 int count;
 public ComMem(int id,int count)
 {
  this.id=id;
  this.count=count;
 }
 public int compareTo(Object o)
 {
  ComMem cm=(ComMem)o;
  int result=this.id-cm.id;//将其注释,去掉下面的注释再看看执行结果
  //int result=this.count-cm.count;
  return result; 
 }
 public boolean equals(Object o)
 {
  ComMem cm=(ComMem)o;
  if(this.count==cm.count)
  return true;
  else
  return false; 
 }
 public int hashCode()
 {
  return count;
 }
 public String toString()
 {
  return "(id:"+id+"|count:"+count+")";
 }
}
public class CompareTo
{
 public static void main(String[] args)
 {
  ComMem cm1=new ComMem(1,1);
  ComMem cm2=new ComMem(1,2);
  ComMem cm3=new ComMem(1,3);
  ComMem cm4=new ComMem(1,4);
  ComMem cm5=new ComMem(1,5);
  TreeSet ts=new TreeSet();
  ts.add(cm1);
  ts.add(cm2);
  ts.add(cm3);
  ts.add(cm4);
  ts.add(cm5);
  System.out.println("TreeSet ts: "+ts);//只添加进了一个cm1
  HashSet hs=new HashSet();
  hs.add(cm1);
  hs.add(cm2);
  hs.add(cm3);
  hs.add(cm4);
  hs.add(cm5);
  System.out.println("HashSet hs: "+hs);//全都添加了进来
 }
}
                                                                                                                                                       

要是我的解释还不够清楚,可以看看Effective Java的11条。
最后强调一点,“基础很重要”,不要在专研J2EE的时候或是大谈struct、spring的时候却忘记了如何合理的重写一个equals。


Valid HTML! Valid CSS!

This is a personal weblog, I do not speak for my employer.