一尘不染

为什么java.lang.Number不实现Comparable?

java

有谁知道为什么
java.lang.Number不执行Comparable?这意味着您无法对排序NumberCollections.sort这在我看来有点奇怪。

讨论后更新:

感谢所有有用的回复。最后,我对该主题进行了更多研究

为什么java.lang.Number不实现Comparable的最简单解释源于可变性问题。

对于位的检讨,java.lang.Number是抽象的超类型的AtomicIntegerAtomicLongBigDecimalBigIntegerByteDoubleFloatIntegerLongShort。在该列表中,AtomicIntegerAtomicLong以没有实现Comparable

深入研究,我发现Comparable在可变类型上实现不是一种好习惯,因为在比较期间或之后对象可能会更改,从而使比较结果无效。这两个AtomicLongAtomicInteger是可变的。API设计人员事先就没有Number实现,Comparable因为这样会限制将来子类型的实现。确实,AtomicLong并且AtomicIntegerjava.lang.Number最初实现之后很久就在Java
1.5中添加了它们。

除了可变性之外,这里可能还需要考虑其他因素。中的compareTo实现Number必须将所有数值都提升为,BigDecimal因为它能够容纳所有Number子类型。对于我来说,这种提升对数学和性能的影响还不清楚,但是我的直觉发现这种解决方法很混乱。


阅读 227

收藏
2020-09-08

共1个答案

一尘不染

值得一提的是以下表达式:

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

始终是false,这往往会使每个人在某个时候绊倒。因此,您不仅不能比较任意Numbers,而且甚至无法确定它们是否相等。

另外,在实原语类型(floatdouble),确定是否两个值相等是棘手的,并且必须在可接受的误差容限内完成。尝试如下代码:

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实例只有六个可用方法:

  • byteValue();
  • shortValue();
  • intValue();
  • longValue();
  • floatValue(); 和
  • doubleValue()

因此,我想Sun做出了(合理的)决定,即Numbers仅Comparable针对自己的实例。

2020-09-08