2012-02-01 14 views
3

Comparableインターフェイスを実装するときは、compareTo()というメソッドを定義することになっているので、次のようなことがドキュメントに記載されています:Java同等の戻り値。正確に1、-1または0でなくてはなりませんか?

  • 全てのxとyのSGN(x.compareTo(Y))== -sgn(y.compareTo(X))。

  • 関係は推移的である。つまり、(x.compareTo(y)> 0 & & y.compareTo(z)が> 0)x.compareTo(Z)> 0を意味しています。

  • x.compareTo(y)== 0は、すべてのzについてsgn(x.compareTo(z))== sgn(y.compareTo(z))を意味します。今

、混乱取得部は、次のようにそれが指定され、戻り値である:

は負の整数、ゼロを返し、このオブジェクト として正の整数が少なく指定されたオブジェクトより大きい、等しい、または大きい

それは、戻り値がこのように限定されている要件として言及されていなくても、ほとんどの実装は1-1または0を返すようです。
次のコードは、このように、クラスのインスタンスを含む(Collections.sort()を使用して)リストの並べ替えのために働くFoo

public int compareTo(Foo other){ 
    return this.value > other.value? 1 : this.value < other.value ? -1 : 0; 
} 

しかしこれはない:

valuelongある
public int compareTo(Foo other){ 
    return (int)(this.value - other.value); 
} 

、および値の差はInteger.MAX_VALUEを超えません。

は、私がここで何かをしないのですか、正確に1-1または0、ドキュメントに矛盾するために必要な戻り値はありますか?

更新:すべてのお返事ありがとうございますが、人間の要因はここに責任があるようです。私は計算された差がInteger.MAX_VALUEより小さいと言いました。これはオーバーフローがないことを意味するはずですが、計算が間違っていたので、私は実際に奇妙な結果を引き起こしたを取得しました。

答えて

7

契約は柔軟性があり、this.value - other.valueイディオム(後で整数のオーバーフローのために間違っていることが判明しました)を可能にしました。しかし、場合によっては、str.length() - str2.length()のように価値があります。 ありそうでない最小長さが0で最大値がInteger.MAX_VALUE0 - Integer.MAX_VALUEはまだInteger.MIN_VALUEより大きい)なので、文字列または配列サイズの比較がオーバーフローする可能性がありません。長さ/サイズで並べ替える必要がある場合に便利です。

また、1/-1と比較するよりも、バイトコード/アセンブリの方が高速/ genrateのほうが速いことが多いため、ユーザーを制限するのはなぜですか?正または負の値を自由に使用することは自由です。

+0

このような制限はありません。必要な負または正の整数を返すことができます。有効なJavaを参照してください。 –

+0

解決策としてこれをマークして、私は実際の問題を見つけることができました。 – Jave

-1

のJavadocも言う:前述の説明において

を、表記SGN(式)は、数学的符号関数を指定し、かどうかに応じて-1のいずれか、0、又は1を返すように定義されexpressionの値は負、ゼロまたは正です。

EDIT:

はい、私は誤解。あなたが正しいです。

+0

はい、しかし、結果に 'sgn'を使わなければならないということは一度も言及されていません。 – Jave

+0

が真です。私は誤解しました。 – Azodious

1

いいえ、任意の整数を返すことができます。あなたは何を得ているのですか?

次のクラスをテストしてください:私は次の出力を得る

public static void main(String[] args) { 

     final ToSort sort0 = new ToSort(-100); 
     final ToSort sort1 = new ToSort(1); 
     final ToSort sort2 = new ToSort(100); 


     List<ToSort> elements = new ArrayList<ToSort>(){{add(sort2); add(sort1); add(sort0);}}; 
     System.out.println("Unsorted:" + elements.toString()); 

     Collections.sort(elements); 

     System.out.println("Sorted:" + elements.toString()); 

    } 

    static class ToSort implements Comparable{ 

     long value; 
     public ToSort(long value){ 
      this.value = value; 
     } 

     @Override 
     public int compareTo(Object other) { 
      return (int) (this.value - ((ToSort)other).value); 
     } 

     public String toString(){ 
      return ""+value; 
     } 
    } 

を:

run: 
Unsorted:[100, 1, -100] 
Sorted:[-100, 1, 100] 
BUILD SUCCESSFUL (total time: 0 seconds) 

あなたは何を実行しているかどうかを確認するためにあなたのcompareTo方法およびデバッグでブレークポイントを追加したい場合がありますあなたは期待している。

+0

エラーはありません。リストはソートされていないプロパティです。ダブルリターンはコピー貼り間違いでした。 – Jave

+0

'new long(1).longValue()'は '1L'です。'(int)(new Long(1).longValue() - その他) 'は' 1 - (int)other'です。 –

+0

@PeterLawreyデモ目的のためだけだった - すでに編集されていますが、 '(int)(long-long)'は '((int)long) - ((int)long)'と同じ結果を返します。 – Marcelo