首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 每日一題(20161108):TreeSet 配合 Comparable 返回 0 的行為分析

     編輯:Java 綜合教學

題目代碼

package Nov2016;
import java.util.TreeSet;

public class Ques1108 {
    public static void main(String[] args){
        Animal dog = new Animal("dog");
        Animal cat = new Animal("cat");
        TreeSet<Animal> animals = new TreeSet<Animal>();
        animals.add(dog);
        animals.add(cat);
        System.out.println(animals); // 注釋 1 處輸出什麼?
    }
}

class Animal implements Comparable<Animal>{
    private String name;
    Animal(String name){ this.name = name; }
    
    @Override
    public int compareTo(Animal o){
        return 0;  // 關鍵:永遠返回 0
    }
    
    @Override
    public String toString(){
        return name;
    }
}

核心分析

  1. TreeSet 依賴 Comparable.compareTo 維護紅黑樹有序性與去重
  2. compareTo 返回 0 表示「相等」(根據 Java 文檔:sgn(x.compareTo(y)) == -sgn(y.compareTo(x)),且 (x.compareTo(y)==0) == (x.equals(y)) 應盡量成立)
  3. 首次 add(dog) 成功,樹中有 1 個節點
  4. 第二次 add(cat):cat.compareTo(dog) == 0 → TreeSet 判定為重複元素 → 拒絕添加,返回 false
  5. 最終集合僅含 dog

輸出結果

[dog]

關鍵知識點

  • TreeSet/TreeMap 去重依據:compareTo == 0 而非 equals()
  • CompareTo 契約:自反性、對稱性、傳遞性;強烈建議與 equals 一致
  • 違反契約後果:集合行為不可預期、難以調試
  • 正確實現:return this.name.compareTo(o.name); 按名字排序去重

擴展思考

若改為 HashSet:依賴 hashCode() + equals(),未重寫則按地址判斷 → [dog, cat] 兩個元素。
這體現了 SortedSet (TreeSet) 與 HashSet 去重語義的本質差異。

答案

輸出:[dog]

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved