[英]How do you implement compareTo methods cleanly?
目前我正在編寫一個用於二次函數的compareTo方法,形式為:ax ^ 2 + bx + c。
a,b,c是通過構造函數傳遞給類的整數系數。
在compareTo方法中,我應該首先比較兩個函數之間的a系數,但如果它們相等,我比較b系數。 如果b是相等的,我比較c。
我為此提出的方法最終變得非常難看:
public int compareTo(QuadraticFunction other)
{
if (a > other.a)
return 1;
else if (a < other.a)
return -1;
else if (b > other.b)
return 1;
else if (b < other.b)
return -1;
else if (c > other.c)
return 1;
else if (c < other.c)
return -1;
else
return 0;
}
所以我想知道,如果你有這些“分層”的比較系統(比如在c之前比較a之前的b),那么實現它們的最佳方法是什么? 如果你不得不經歷10多個變量,我無法想象會像我一樣編寫一個方法。
對於任意數量的系數(所有相同類型),您應該將它們存儲在List
(或類似的東西)中,而不是單獨命名的成員變量。 這允許您將示例代碼轉換為迭代。
Guava Libraries提供了一個非常好的工具,稱為ComparisonChain 。
您的代碼看起來像這樣:
import com.google.common.base.ComparisonChain;
...
public int compareTo(QuadraticFunction other) {
return ComparisonChain.start()
.compare(a, other.a)
.compare(b, other.b)
.compare(c, other.c)
.result();
}
為了便於閱讀,並使用a,b,c的內置比較方法,我將重構為:
public int compareTo(QuadraticFunction other) {
if (a.equals(other.a)) {
if (b.equals(other.b))
return c.compareTo(other.c);
return b.comapreTo(other.b);
}
return a.compareTo(other.a);
}
此代碼假定字段為Number
。 如果他們是原始的,或者將它們轉換為包裹型或改變a.equals(b) to
一個== b and change
a.compareTo(b)中to
一個- B`。
還要注意,當if
返回時,永遠不需要else
- 它是多余的,所以刪除它。
您可以使用如下所示的成語,將比較分為按字段清除的部分,每個字段只需要一次測試,並使用signum
方法生成返回值。
注意,下面的減法適用於int
, short
, char
或byte
字段。 對於long
, float
和double
字段,您必須對<
和==
使用單獨的檢查以避免上溢/下溢,並且由於舍入而導致精度損失。 比較浮點值時要小心NaN
。 對於Comparable
字段,您可以在使用單獨的條件處理null
之后將delta設置為compareTo
的結果。
long delta = ((long) a.field1) - b.field1;
if (delta != 0) { return Long.signum(delta); }
delta = ((long) a.field2) - b.field2;
if (delta != 0) { return Long.signum(delta); }
...
return 0;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.