1. ホーム
  2. java

[解決済み] java.lang.NumberはなぜComparableを実装しないのですか?[重複しています]

2022-05-03 05:59:06

質問

なぜかわかる方いらっしゃいますか? java.lang.Number は実装されていません。 Comparable ? これは、ソートできないことを意味します。 Number との Collections.sort というのは、ちょっと不思議な気がします。

ポストディスカッションの更新。

いろいろと参考になる回答ありがとうございました。結局、私が行ったのは このトピックについて、もう少し調べてみました .

java.lang.NumberがComparableを実装しない最も単純な理由は、変異性の懸念に根ざしています。

ちょっと復習のために。 java.lang.Number の抽象的なスーパータイプです。 AtomicInteger , AtomicLong , BigDecimal , BigInteger , Byte , Double , Float , Integer , LongShort . そのリストには AtomicIntegerAtomicLong を実装しないようにします。 Comparable .

いろいろと調べてみると、実装する際に Comparable なぜなら、比較中または比較後にオブジェクトが変更される可能性があり、比較結果が無意味になってしまうからです。どちらも AtomicLongAtomicInteger はミュータブルです。API設計者は先見の明をもって Number インプリメント Comparable なぜなら、それは将来のサブタイプの実装を制約することになるからです。確かに AtomicLongAtomicInteger が追加されたのは、Java 1.5で java.lang.Number が最初に実装されました。

ミュータビリティとは別に、おそらくここでも他の考慮事項があるはずです。A compareTo の実装は Number は、すべての数値を BigDecimal をすべて収容することができるため Number というサブタイプがあります。数学的な意味合いとパフォーマンスの観点から、このプロモーションの意味合いは私には少し不明ですが、私の直感では、この解決策はこじつけだと思います。

どのように解決するのか?

特筆すべきは、以下の式です。

new Long(10).equals(new Integer(10))

は常に false これは、誰もがどこかでつまずきがちなことです。 ですから、任意の Number が、等しいかどうかさえ判断できない。

また、本当のプリミティブ型( float , double ) の場合、2つの値が等しいかどうかを判断するのは厄介で、許容誤差の範囲内で行わなければならない。 次のようなコードを試してみてください。

double d1 = 1.0d;
double d2 = 0.0d;
for (int i=0; i<10; i++) {
  d2 += 0.1d;
}
System.out.println(d2 - d1);

をクリックすると、何か小さな違いが残ります。

という問題に話を戻すと Number Comparable . どのように実装するのでしょうか? 次のようなものを使って doubleValue() は、確実に実行できないでしょう。 そのため Number のサブタイプは

  • Byte ;
  • Short ;
  • Integer ;
  • Long ;
  • AtomicInteger ;
  • AtomicLong ;
  • Float ;
  • Double ;
  • BigInteger そして
  • BigDecimal .

信頼性の高いコーディングをお願いします compareTo() メソッドは、一連の if instanceof ステートメントに陥らないのでしょうか? Number インスタンスが利用できるメソッドは6つだけです。

  • byteValue() ;
  • shortValue() ;
  • intValue() ;
  • longValue() ;
  • floatValue() そして
  • doubleValue() .

という(合理的な)判断をサンはしたのでしょう。 Number のみでした。 Comparable を自分自身のインスタンスにする。