关于TreeSet更新元素(的排序依据)后删除

转自:http://dracularking.javaeye.com/blog/712090

  知道TreeSet的backing map是TreeMap,看程序:
Java代码 复制代码 收藏代码
  1. import java.util.TreeSet;   
  2.   
  3.  class R implements Comparable<Object> {   
  4.     int count;   
  5.   
  6.     public R(int count) {   
  7.         this.count = count;   
  8.   
  9.     }   
  10.   
  11.     public String toString() {   
  12.         return "R(count:" + count + ")";   
  13.   
  14.     }   
  15.   
  16.     public boolean equals(Object o) {   
  17.         if (o instanceof R) {   
  18.             R r = (R) o;   
  19.             if (this.count == r.count)   
  20.                 return true;   
  21.         }   
  22.         return false;   
  23.     }   
  24.   
  25.     public int compareTo(Object o) {   
  26.         R r = (R) o;   
  27.         if (this.count > r.count)   
  28.             return 1;   
  29.         else if (this.count == r.count)   
  30.             return 0;   
  31.         else  
  32.             return -1;   
  33.     }   
  34. }   
  35.   
  36.  public class TestTreeSetError {   
  37.   
  38.     /**  
  39.      * @param args  
  40.      */  
  41.     public static void main(String[] args) {   
  42.         // TODO Auto-generated method stub   
  43.         TreeSet<R> ts = new TreeSet<R>();   
  44.         ts.add(new R(5));   
  45.         ts.add(new R(-3));   
  46.         ts.add(new R(9));   
  47.         ts.add(new R(-2));   
  48.         System.out.println("1 = " + ts);   
  49.         R first = (R) ts.first();   
  50.         first.count = 20;   
  51.         System.out.println("2 = " + ts);   
  52.         R last = (R) ts.last();   
  53.         last.count = -2;   
  54.         System.out.println("3 = " + ts);   
  55.         System.out.println(ts.remove(new R(-2)));   
  56.         System.out.println(ts);   
  57.         System.out.println(ts.remove(new R(5)));   
  58.         System.out.println(ts);   
  59.         System.out.println(ts.remove(new R(-2)));   
  60.         System.out.println(ts);   
  61.   
  62.     }   
  63. }  
import java.util.TreeSet;

class R implements Comparable<Object> {
	int count;

	public R(int count) {
		this.count = count;

	}

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

	}

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

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

public class TestTreeSetError {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TreeSet<R> ts = new TreeSet<R>();
		ts.add(new R(5));
		ts.add(new R(-3));
		ts.add(new R(9));
		ts.add(new R(-2));
		System.out.println("1 = " + ts);
		R first = (R) ts.first();
		first.count = 20;
		System.out.println("2 = " + ts);
		R last = (R) ts.last();
		last.count = -2;
		System.out.println("3 = " + ts);
		System.out.println(ts.remove(new R(-2)));
		System.out.println(ts);
		System.out.println(ts.remove(new R(5)));
		System.out.println(ts);
		System.out.println(ts.remove(new R(-2)));
		System.out.println(ts);

	}
}

树添加修改稳定之后,形成的红黑树是这样的:

          5

20              -2
      -2

第二层-2是20的右子节点,因为删除时循根搜索,-2一直往左路搜,最后搜到20左子节点为空,所以删除失败,待5删除之后,重新平衡了树结构:

     -2

20      -2

因此-2就能被删除

这其中涉及到了TreeSet中的remove:

Java代码 复制代码 收藏代码
  1. public boolean remove(Object o) {   
  2.     return m.remove(o)==PRESENT;   
  3. }  
public boolean remove(Object o) {
    return m.remove(o)==PRESENT;
}

TreeMap中的remove:

Java代码 复制代码 收藏代码
  1. public V remove(Object key) {   
  2.         Entry<K,V> p = getEntry(key);   
  3.         if (p == null)   
  4.             return null;   
  5.   
  6.         V oldValue = p.value;   
  7.         deleteEntry(p);   
  8.         return oldValue;   
  9. }  
public V remove(Object key) {
        Entry<K,V> p = getEntry(key);
        if (p == null)
            return null;

        V oldValue = p.value;
        deleteEntry(p);
        return oldValue;
}

最终到TreeMap的getEntry:

Java代码 复制代码 收藏代码
  1. final Entry<K,V> getEntry(Object key) {   
  2.         // Offload comparator-based version for sake of performance   
  3.         if (comparator != null)   
  4.             return getEntryUsingComparator(key);   
  5.         if (key == null)   
  6.             throw new NullPointerException();   
  7.     Comparable<? super K> k = (Comparable<? super K>) key;   
  8.         Entry<K,V> p = root;   
  9.         while (p != null) {   
  10.             int cmp = k.compareTo(p.key);   
  11.             if (cmp < 0)   
  12.                 p = p.left;   
  13.             else if (cmp > 0)   
  14.                 p = p.right;   
  15.             else  
  16.                 return p;   
  17.         }   
  18.         return null;   
  19. }  
posted @ 2011-03-20 19:29  白辉  阅读(715)  评论(0编辑  收藏  举报