Jul*_*ang 132 java sorting comparable
有谁知道为什么 java.lang.Number不实施Comparable?这意味着你无法排序Numbers的Collections.sort这对我来说有点陌生.
发布讨论更新:
java.lang.Number未实现Comparable的原因的最简单解释源于可变性问题.
对于位的检讨,java.lang.Number是抽象的超类型的AtomicInteger,AtomicLong,BigDecimal,BigInteger,Byte,Double,Float,Integer,Long和Short.在那个列表上,AtomicInteger并AtomicLong没有实现Comparable.
四处搜索,我发现Comparable在可变类型上实现这不是一个好习惯,因为对象在比较期间或之后可能会发生变化,因此比较结果无用.这两个AtomicLong和AtomicInteger是可变的.API设计者已经预见到没有Number实现,Comparable因为它会限制未来子类型的实现.确实,AtomicLong并且AtomicInteger在java.lang.Number最初实现之后很久就被添加到Java 1.5中.
除了可变性之外,这里也可能有其他考虑因素.一compareTo实施Number就必须促进所有的数字值BigDecimal,因为它是能够容纳所有的Number子类型.这种促销在数学和表现方面的含义对我来说有点不清楚,但我的直觉发现了解决方案.
cle*_*tus 63
值得一提的是以下表达式:
new Long(10).equals(new Integer(10))
Run Code Online (Sandbox Code Playgroud)
永远是false,这往往会使每个人在某个时刻绊倒.因此,您不仅无法比较任意Numbers,而且甚至无法确定它们是否相等.
此外,对于真实的原始类型(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);
Run Code Online (Sandbox Code Playgroud)
你会留下一些小小的差异.
所以回到制作的问题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做出的(合理的)决定Number只是Comparable针对自己的例子.
Edd*_*die 42
有关答案,请参阅Java bugparade bug 4414323.您还可以从comp.lang.java.programmer中找到讨论
引用Sun对2001年错误报告的回应:
所有"数字"都不具有可比性; 可比较假定数字的总排序是可能的.浮点数甚至都不是这样; NaN(不是数字)既不小于,也不大于,也不等于任何浮点值,甚至本身.{Float,Double} .compare强加一个不同于浮点"<"和"="运算符排序的总排序.此外,如当前实现的那样,Number的子类仅与同一类的其他实例相当.还有其他情况,例如复数,其中不存在标准总排序,尽管可以定义一个.简而言之,Number的子类是否具有可比性应留作该子类的决定.
为了尝试解决原始问题(对数字列表进行排序),一种选择是声明扩展 Number 并实现 Comparable 的泛型类型的列表。
就像是:
<N extends Number & Comparable<N>> void processNumbers(List<N> numbers) {
System.out.println("Unsorted: " + numbers);
Collections.sort(numbers);
System.out.println(" Sorted: " + numbers);
// ...
}
void processIntegers() {
processNumbers(Arrays.asList(7, 2, 5));
}
void processDoubles() {
processNumbers(Arrays.asList(7.1, 2.4, 5.2));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
30092 次 |
| 最近记录: |