2013-10-22 126 views
2

我得到這個代碼:Java的比較類實例

public Class Car; 
{ 
    private String name; 
    public int number;  


    public Car(String name, int number) 
    { 
     this.name = name; 
     this.number = number; 
    } 

    // this class also got getters and setters 

後來我有另一個類:

public class CarList 
    { 
     private Collection<Car> cars; 


     public CarList() 
     { 
      cars = new HashSet<>(); 
     } 


     public boolean insertCar(Car car) 
     { 
      return cars.add(car); 
     } 

然後碼連續用一些其他的方法,但它們都沒有問題。 如果我創建了Car類的兩個實例,例如car1(mazda,1)car2(porsche,2),然後我調用方法insertCar,則一切正常,方法返回true,因爲有兩輛車具有不同的名稱和編號。

但是,如果創建例如car1(mazda,1)然後car2(porsche,1)方法返回true儘管事實上,汽車的數量是相同的。

編輯:所以我的問題是如何強制方法返回false當我嘗試''添加'具有相同的數字和相同的名稱的汽車(所以如何將@Override等於()方法改變)?

+8

你需要實現Car.equals()和Car.hashCode( ) – iluxa

+0

如果想要表示一個唯一的ident,我會試圖將「number」重命名爲「id」 ifier。 – pamphlet

回答

1

首先,您的Car類將不會按照原樣編譯。 Class應該是class,並且在Car之後你有一個分號。我會認爲這只是個錯誤而已。

對於你的任務,你必須做下面的代碼中的修改:

  • 覆蓋equals()hashCode()方法Car類,在那裏你只需考慮對象比較,和hashCode計算number屬性。

    @Override 
    public boolean equals(Object ob) { 
        if (!ob instanceof Car) return false; 
        Car that = (Car)ob; 
        return this.number == that.number; 
    } 
    
    @Override 
    public int hashCode() { 
        return number; 
    } 
    
  • CarList類,而不是Collection<Car>使用Set<Car>。這將自動處理重複。 Set#add(E)方法僅在Set不存在的情況下才會將元素添加到Set中(這是在equalshashCode的基礎上測試的,因此您需要重寫它們)。如果該元素已經存在,那麼它不會修改該集合,並按照您的要求返回false。 (糟糕,錯過了你實際上僅在你的班級中實例化了一個HashSet,最好重命名爲Set<Car>)。


相關:

+0

謝謝,這真的很有幫助。我只有另一個問題:當我考慮用於對象比較的''數字''&&'name''屬性時,equals()如何改變? –

0

有幾種選擇適合您,哪一個最好取決於您的CarList課程的使用場景。

對當前代碼最直接的修改是將代碼添加到Add方法中,通過列表中的所有車輛並檢查是否已經存在具有相同編號的另一輛車。如果是這樣,那麼不要添加並返回FALSE。

但是,上述將有插入的二次性能,這可能不會對你很好。

相反,更好的選擇是使用額外的數據結構,例如已經在列表中的所有車號的HasSet。添加時,請檢查重複項的設置,如果您添加的號碼已存在,則返回false。

HashSet<Integer> carNumbers = new HashSet<Integer>(); 
public boolean insertCar(Car car) 
{ 
    if(!carNumbers.contains(car.getNumber())) 
    { 
     carNumbers.put(car.getNumber()); 
     return cars.add(car); 
    } 

    return false; 
} 
0

你需要重寫equals方法Car。在該方法中,提供您想要確定兩個對象是否相同的邏輯。

@override 
public boolean equals(Car car) { 
    return car.name == this.name && car.number == this.number; 
} 

或者任何你希望該方法滿足的條件。

0

假設你是Java。

給出兩個對象,需要確定它們是否相同。一個是內存位置1000000的Car,另一個是1200000的Cat。看起來不同。完成。

儘管Java做了一個額外的步驟:「對象是否有equals()方法?」如果是這樣,它會被調用,並且對象本身可以決定它是否與另一個相等。如果不是這樣,則會回到「他們是否是同一個實例?」

所以,如果你重寫equals()方法,像

@Override 
public boolean equals(Object ob) { 
    if (!(ob instanceOf Car)) { return false; } 
    Car other = (Cat)ob; 
    // decide whether they're equal and return true/false 
} 

那麼這是朝着正確方向邁出的一步。第二部分是hashCode()。該合同是這樣的:

如果a1.equals(A2)然後a1.hashCode()== a2.hashCode()

所以,相同的物品必須產生相同的散列碼。但是,不同的對象也可能產生相同的散列碼。

+0

第一行是什麼? –

0

HashSet的答案會起作用,但是他們認爲你永遠不會想要在任何用例中使用相同數量和不同名稱的兩輛汽車。

如果您只想在此用例中使用此行爲(例如,該數字在CarList中是唯一的,但通常不是),則可以使用帶有自定義Comparator的TreeSet。作爲附加功能,列表將自動按照編號排序。

cars = new TreeSet<>(new Comparator<>(){ 
    public int compare(Car a, Car b){ 
     return a.number - b.number; 
    } 
}); 

在這種情況下,您不需要實現equals()或hashCode()。

+0

如果比較返回0,它將避免重複。 – greyfairer

0

修改類如下: 汽車

public class Car { 

private String name; 
public int number; 

public Car(String name, int number) { 
    this.name = name; 
    this.number = number; 
} 

@Override 
public boolean equals(Object ob) { 
    if (!(ob instanceof Car)) { 
     return false; 
    } 
    Car car = (Car) ob; 
    return this.number == car.number; 
} 

@Override 
public int hashCode() { 
    return number; 
} 
} 

汽車榜單

public class CarList { 

private Set<Car> cars; 

public CarList() { 
    cars = new HashSet<Car>(); 
} 

public boolean insertCar(Car car) { 
    return cars.add(car); 
} 

}

+0

代碼唯一答案在SO上不可接受。至少解釋爲什麼這會起作用。除此之外,這與我的回答有什麼不同? –