为什么java.lang.Number没有实现Comparable? [英] Why doesn't java.lang.Number implement Comparable?
问题描述
有谁知道为什么 java.lang.Number
没有实现 Comparable
?这意味着您无法使用 Collections.sort
对 Number
进行排序,这在我看来有点奇怪。
发布讨论更新:
感谢所有有用的回复。我最终做了关于这个主题的更多研究。
为什么java.lang.Number没有实现Comparable的最简单的解释是根植于可变性问题。
对于一些评论, java.lang.Number
是 AtomicInteger的抽象超类型
, AtomicLong
, BigDecimal
, BigInteger
,字节
, Double
, Float
,整数
,长
和短
。在该列表中, AtomicInteger
和 AtomicLong
未实现 Comparable
。
我发现在可变类型上实现 Comparable
并不是一个好习惯,因为对象可以在比较期间或之后进行更改,从而使比较结果无效。 AtomicLong
和 AtomicInteger
都是可变的。 API设计者已经预见到没有 Number
实现 Comparable
因为它会限制未来子类型的实现。实际上,在 java.lang.Number <之后很久就在Java 1.5中添加了
AtomicLong
和 AtomicInteger
/ code>最初实施。
除了可变性之外,这里也可能有其他考虑因素。
中的 compareTo
实现必须将所有数值提升为 BigDecimal
因为它能够容纳所有 Number
子类型。这个促销在数学和表现方面的含义对我来说有点不清楚,但我的直觉发现解决方案kludgy。
值得一提的是以下表达式:
new Long(10).equals(new Integer(10))
始终是 false
,这往往会让每个人都感到震惊某种观点。因此,您不仅无法比较任意数字
,而且您甚至无法确定它们是否相等。
此外,使用真实的原始类型( float
, double
),确定两个值是否相等是棘手的并且必须在可接受的误差范围内完成。尝试以下代码:
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()
这样的东西不会可靠。请记住数字
子类型是:
-
字节
; -
短
; -
整数
; -
长
; -
AtomicInteger
; -
AtomicLong
; -
Float
; -
Double
; -
的BigInteger
;和 -
BigDecimal
。
你能编写一个可靠的 compareTo()
方法,它不会转换成一系列if instanceof语句吗? 数字
实例只有六种方法可供他们使用:
-
byteValue()
; -
shortValue()
; -
intValue()
; -
longValue()
; -
floatValue()
;和 -
doubleValue()
。
所以我猜Sun做出了(合理的)决定 Number
s只有 Comparable
到他们自己的实例。 / p>
Does anyone know why java.lang.Number
does not implement Comparable
? This means that you cannot sort Number
s with Collections.sort
which seems to me a little strange.
Post discussion update:
Thanks for all the helpful responses. I ended up doing some more research about this topic.
The simplest explanation for why java.lang.Number does not implement Comparable is rooted in mutability concerns.
For a bit of review, java.lang.Number
is the abstract super-type of AtomicInteger
, AtomicLong
, BigDecimal
, BigInteger
, Byte
, Double
, Float
, Integer
, Long
and Short
. On that list, AtomicInteger
and AtomicLong
to do not implement Comparable
.
Digging around, I discovered that it is not a good practice to implement Comparable
on mutable types because the objects can change during or after comparison rendering the result of the comparison useless. Both AtomicLong
and AtomicInteger
are mutable. The API designers had the forethought to not have Number
implement Comparable
because it would have constrained implementation of future subtypes. Indeed, AtomicLong
and AtomicInteger
were added in Java 1.5 long after java.lang.Number
was initially implemented.
Apart from mutability, there are probably other considerations here too. A compareTo
implementation in Number
would have to promote all numeric values to BigDecimal
because it is capable of accommodating all the Number
sub-types. The implication of that promotion in terms of mathematics and performance is a bit unclear to me, but my intuition finds that solution kludgy.
It's worth mentioning that the following expression:
new Long(10).equals(new Integer(10))
is always false
, which tends to trip everyone up at some point or another. So not only can you not compare arbitrary Number
s but you can't even determine if they're equal or not.
Also, with the real primitive types (float
, double
), determining if two values are equal is tricky and has to be done within an acceptable margin of error. Try code like:
double d1 = 1.0d;
double d2 = 0.0d;
for (int i=0; i<10; i++) {
d2 += 0.1d;
}
System.out.println(d2 - d1);
and you'll be left with some small difference.
So back to the issue of making Number
Comparable
. How would you implement it? Using something like doubleValue()
wouldn't do it reliably. Remember the Number
subtypes are:
Byte
;Short
;Integer
;Long
;AtomicInteger
;AtomicLong
;Float
;Double
;BigInteger
; andBigDecimal
.
Could you code a reliable compareTo()
method that doesn't devolve into a series of if instanceof statements? Number
instances only have six methods available to them:
byteValue()
;shortValue()
;intValue()
;longValue()
;floatValue()
; anddoubleValue()
.
So I guess Sun made the (reasonable) decision that Number
s were only Comparable
to instances of themselves.
这篇关于为什么java.lang.Number没有实现Comparable?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!