求高手解释一下 ???处为什么第一次删除失败,第二次删除成功
源代码:
import java.util.TreeSet; class R implements Comparable{ 
int count; 
public R(int count){ 
   this.count = count; 

public String toString(){ 
   return "R(count属性:"+count+")"; 

public boolean equals(Object obj){ 
   if(obj instanceof R){ 
    R r = (R)obj; 
    if(r.count == this.count){ 
     return true; 
    } 
   } 
   return true; 

public int compareTo(Object obj){ 
   R r = (R)obj; 
   if(this.count > r.count) 
   { 
    return 1; 
   } 
   else if(this.count == r.count){ 
    return 0; 
   } 
   else { 
    return -1; 
   } 


public class TestTreeSet2 { /** 
* @param args 
*/ 
public static void main(String[] args) { 
   // TODO Auto-generated method stub 
   TreeSet ts = new TreeSet(); 
   ts.add(new R(5)); 
   ts.add(new R(-3)); 
   ts.add(new R(9)); 
   ts.add(new R(-2)); 
   System.out.println(ts); 
     // 取出第一个元素 
   R frist = (R)ts.first(); 
   //改变其属性值 
   frist.count = 20; 
   //取出最后一个元素 
   R last = (R)ts.last(); 
   //改变其属性值 
   last.count = -2; 
   System.out.println(ts);
 
   //删除已更改的元素失败 -----???
   System.out.println(ts.remove(new R(-2))); 
   System.out.println(ts); 
   //删除未更改的元素成功 
   ts.remove(new R(5)); 
   System.out.println(ts);    //删除已更改的元素成功 -----???
   System.out.println(ts.remove(new R(-2))); 
   System.out.println(ts); 

解决方案 »

  1.   

    1、看了一下jdk5的api,结果是Comparable只能完成在元素在TreeSet中的排序功能,也就是说,你的Comparable与ts的remove方法是没有关系的2、
    ts.remove(new R(-2));
    你觉得有这种写法吗?new是新分配一个对象你在ts里面删除一个新建的对象,至少也应该是在ts里面已有的对象PS:你在ts.add(new R(-2))中的R(-2)对象和ts.remove(new R(-2))中的R(-2)这是两个不同的对象
      

  2.   

    TreeSet底层实际存储容器时TreeMap,采用“红黑树”来保存集合的Entry.
    ts.add(new R(5));  
    ts.add(new R(-3));  
    ts.add(new R(9));  
    ts.add(new R(-2)); 
    你自己画一下平衡二叉树,5是根节点,-3是左节点,9是右节点,-2是-3的右节点frist.count = 20;  
    last.count = -2;  
    引用first指向最小元素对象后,改变了里面的值,但存储位置没有改变。
    引用last指向最大元素对象后,改变了里面的值,但存储位置没有改变。再次调用ts.remove(new R(-2));
    会找到离根节点较近的-2,但是原来的值是9,所以删除失败ts.add(new R(5)); 
    ts.add(new R(6)); 
    ts.add(new R(7)); 
    ts.add(new R(-3));  
    ts.add(new R(9));  
    ts.add(new R(-2)); 如果改成这样子
    ts.remove(new R(-2));
    第一次就会删除成功了。另外建议重写hashCode,虽然这里似乎没有关系。
      

  3.   


    TreeSet是SortedSet的子类,是靠Comparable接口中的compareTo()方法来维护一个顺序的
    如果不实现Comparable接口,怎么来对元素排列,构成红黑树?
      

  4.   

    看了一段时间,我发现似乎 TreeSet没有那么高级,当你直接更改某个元素的时候,set不会自动更新内部数据,所以更新数据的工作得自己来编写了,最好还是直接删除-3然后添加20,然后如果想在set中添加-2,也直接用add方法,而不直接更改数据。