簡體   English   中英

你如何干凈地實現compareTo方法?

[英]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方法生成返回值。

注意,下面的減法適用於intshortcharbyte字段。 對於longfloatdouble字段,您必須對<==使用單獨的檢查以避免上溢/下溢,並且由於舍入而導致精度損失。 比較浮點值時要小心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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM