2015-12-02 42 views
3

在另一問題,我的代碼有這樣的equals方法:不同單位的長度比較使用「equals」是不好的?

public class Length { 

    private final double value; 
    private final Unit unit; 

    public Length(double value, Unit unit) { 
     this.value = value; 
     this.unit = unit; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     Length length = (Length) obj; 
     return this.unit.toMM(this.value) == length.unit.toMM(length.value); 
    } 
} 

我希望比較兩個Length S,它們彼此相等,如果它們可以被轉換爲相同的單元具有相同的長度值

@weston在this answer給我提供了一些非常好的解釋,爲什麼我不應該在這裏使用equals,但我還是不太清楚。

+0

這還不清楚。我沒有在鏈接的答案中讀過,你不應該重寫'equals'。 – Tunaki

+0

這似乎主要是一個意見。在'equals()'中引用其他類型/值是不常見的,但如果這就是你的對象如何定義相等性,那麼它就是如何定義相等性的。檢查「值」本身是否相等,「單位」是「相等」(但是該類型定義相等)可能更直接。 – David

+0

查看第二段,「如果你想要這樣的行爲,給它一個名字(建議isSameLength)'這是平等的,而不是等價的' – Freewind

回答

3

從本質上講,他說10mm1cm不應該是平等的。這是有爭議的,由您來決定。

作爲參考,你可以採取類似的方法來BigDecimal的:

new BigDecimal("1.0").equals(new BigDecimal("1.00")) //false 
new BigDecimal("1.0").compareTo(new BigDecimal("1.00")) //0 

另一個例子是java.time.Period

注意,這意味着一段時間‘15個月’的是不等於「1年3個月」。

或者你也可以決定10毫米和1釐米是相等的。以舉例java.time.Duration

該比較基於持續時間的總長度。

最後,重要的是清楚記錄正在完成的工作。

+0

感謝這些偉大的例子!我想也許我應該遵循@ weston的建議,因爲如果我定義了'equals',我應該定義'hashcode',但是如果我正確地定義了它,我應該再次執行'this.unit.toMM(this.value)' 'hashcode'使其正確。那看起來很奇怪。我發現'java.time.Duration'包含了它所需的所有值,並且不需要在'hashcode'中進行額外的轉換 – Freewind