2014-02-17 59 views
1

這是我的代碼:Java:在NavigableSet中添加相同的對象被拒絕

import java.util。*;

public class AnotherBackedCollectionsTest{ 

public static void main(String... args){ 

    Shape square = new Shape("square"); 
    Shape circle = new Shape("circle"); 
    Shape triangle = new Shape("triangle"); 

    NavigableSet<Shape> shapes = new TreeSet<Shape>(); 
    shapes.add(square); 
    shapes.add(circle); 
    shapes.add(triangle); 

    System.out.println("New shape added? " +shapes.add(new Shape("square"))); 

    for(Shape s : shapes){ 
     System.out.println(s.getName()); 
    } 


    Set<Shape> shapes2 = new HashSet<Shape>(); 
    shapes2.add(square); 
    shapes2.add(triangle); 
    shapes2.add(circle); 

    System.out.println("New shape added? " +shapes2.add(new Shape("square"))); 

    for(Shape s : shapes2){ 
     System.out.println(s.getName()); 
    } 

} 

}

class Shape implements Comparable<Shape>{ 

private String name; 

public Shape(String name){ 
    this.name = name; 
} 

public String getName(){ 
    return this.name; 
} 

public int compareTo(Shape shape){ 
    return this.name.compareTo(shape.getName()); 
} 

}

而且我得到這樣的輸出:

New shape added? false 
circle 
square 
triangle 
New shape added? true 
triangle 
square 
square 
circle 

正如你所看到的,我並沒有覆蓋Shape對象的equals()方法。當我在NavigableSet中嘗試添加另一個名稱爲「square」的Shape對象時,我發現這裏奇怪的是它以某種方式拒絕了它。是因爲Shape implements Comparable<T>所以它使用覆蓋compareTo()方法來確定方法相等?

基本上,我想問的是NavigableSet如何確定我試圖添加一個重複的對象,其中,我沒有重寫equals()方法。

回答

2

TreeSet不使用equals()來比較元素。它使用接口Comparable

documentation

一個TreeSet例如使用其compareTo(或compare)方法,所以被認爲等於通過該方法的兩個元件是對所有元素的比較,從所述一組的角度來看,等於。

由於文件還指出,如果你希望你的設置,以滿足一般的Set合同,你必須以一種方式與compareTo()一致的定義equals()

一套的行爲是良好即使其排序與平等不一致也定義;它只是不服從Set接口的總體合同。

在另一方面,HashSet確實使用equals()hashCode(),並且不理compareTo()

這解釋了行爲上的差異。

簡而言之,爲了使您的元素儘可能兼容,請確保覆蓋equals()hashCode(),並實現Comparable接口。

+0

也許這個問題很快就被編輯了。對於'HashSet',都需要'equals'和'hashCode'。應該與'compareTo'一致。我相信你可以在Oracle Java SE 8中用'HashSet'獲得**奇怪的行爲。 –