这是SCJP考试的一道题目,我知道答案,但不知道为什么是这个答案!真的希望高手能给我指点讲解!我真的是感激不尽!
Given:
1. public class Drink implements Comparable{
2. public String name;
3. public int compareTo(Object o){
4. return 0;
5. }
6. }
and:
20. Drink one = new Drink();
21. Drink two = new Drink();
22. one.name = "Coffee";
23. two.name = "Tea";
24. TreeSet set = new TreeSet();
25. set.add(one);
26. set.add(two);
A programmer iterates over the TreeSet and prints the name of each Drink object.
What is the result?
A. Tea
B. Coffee
C. Coffee Tea
D. Compilation fails.
E. The code runs with no output.
F. An exception is thrown at runtime.
答案:B

解决方案 »

  1.   

    public int compareTo(Object o){
    无论什么情况都是返回0 也就是说2个对象永远是相等的
    而SET是不允许重复元素的 所以只能添加第一个对象进去
      

  2.   

    建议追踪一下TreeSet的源代码
    当add的时候,会依次调用集合中现有元素的compareTo方法与新加对象比较
    你再查一下Comparable接口中这个方法的定义,返回的int值为0代表两个对象相等
    TreeSet杜绝相等的对象加入
    因此本题中只加入了第一个对象
    而第二个对象没有加进去不知说明是否详细
      

  3.   

    按照1楼所说,那如果把TreeSet改为HashSet结果也是相同喽??我觉得问题应该在Drink类和TreeSet 这两个类上。
    TreeSet的 public boolean add(E o) {
    return m.put(o, PRESENT)==null;
        }
    而m是TreeMap类型的,TreeMap的put方法如下public V put(K key, V value) {
            Entry<K,V> t = root;        if (t == null) {
                incrementSize();
                root = new Entry<K,V>(key, value, null);
                return null;
           }        while (true) {
                int cmp = compare(key, t.key);
                if (cmp == 0) {
                    return t.setValue(value);
                } else if (cmp < 0) {
                    if (t.left != null) {
                        t = t.left;
                    } else {
                        incrementSize();
                        t.left = new Entry<K,V>(key, value, t);
                        fixAfterInsertion(t.left);
                        return null;
                    }
                } else { // cmp > 0
                    if (t.right != null) {
                        t = t.right;
                    } else {
                        incrementSize();
                        t.right = new Entry<K,V>(key, value, t);
                        fixAfterInsertion(t.right);
                        return null;
                    }
                }
            }
        }
    注意那个compare方法, private int compare(K k1, K k2) {
            return (comparator==null ? ((Comparable</*-*/K>)k1).compareTo(k2)
                                     : comparator.compare((K)k1, (K)k2));
        }
    因为Drink的compareTo返回0,所以compare一直返回0,再看t的setValue方法        public V setValue(V value) {
                V oldValue = this.value;
                this.value = value;
                return oldValue;
            }
      

  4.   

    TreeSet在add元素时会根据comparable来比较添加的元素和已有的元素是否相同的
      

  5.   

    是的 我在回帖中说明了TreeSet的判断方式
    HashSet是不一样的 机制更为复杂
    hash&&(==|equals)
    这个表达式为真 HashSet判定对象相等还是那句话 去看看源码就知道了