java.lang.Comparable#compareTo
方法声明为第一条
实现者必须确保sgn(x.compareTo(y))== -sgn(y.compare- 至(x))所有x和y。 (这意味着x.compareTo(y)必须抛出 当且仅当y.compareTo(x)抛出异常时才会出现异常。)
并根据约书亚布洛赫在第12项的有效Java中的说明
这个技巧在这里工作正常,但应谨慎使用。 除非您确定有问题的字段,否则请勿使用它 非负面的,或者更一般地说,是否存在差异 最低和最高可能字段值小于或等于 Integer.MAX_VALUE(231-1)。这个技巧并不总是奏效的原因 是一个有符号的32位整数不足以容纳 两个任意有符号32位整数之间的差异。如果我是 大的正int和j是一个大的负int,(i - j)会 溢出并返回负值。生成的compareTo方法 将返回一些参数的错误结果并违反第一个参数 和compareTo合同的第二条款。这不是纯粹的 理论问题:它在实际系统中引起了失败。这些 失败可能很难调试,因为破坏的compareTo方法 适用于大多数输入值。
如果整数溢出,你可以违反第一条规定而我无法找到,这个例子说明了第一条规定将如何被违反:
public class ProblemsWithLargeIntegers implements Comparable<ProblemsWithLargeIntegers> {
private int zas;
@Override
public int compareTo(ProblemsWithLargeIntegers o) {
return zas - o.zas;
}
public ProblemsWithLargeIntegers(int zas) {
this.zas = zas;
}
public static void main(String[] args) {
int value1 = ...;
int value2 = ...;
ProblemsWithLargeIntegers d = new ProblemsWithLargeIntegers(value1);
ProblemsWithLargeIntegers e = new ProblemsWithLargeIntegers(value2);
if (!(Math.signum(d.compareTo(e)) == -Math.signum(e.compareTo(d)))){
System.out.println("hey!");
}
}
所以我想要value1
和value2
来获取它?任何的想法?或约书亚错了?
答案 0 :(得分:3)
嗯,这违反了一般合同。例如,取value1 = Integer.MIN_VALUE
和value2 = 1
。这将有效地报告Integer.MIN_VALUE > 1
。
int value1 = Integer.MIN_VALUE;
int value2 = 0;
两次比较都会得到否定结果,因为Integer.MIN_VALUE - 0
== 0 - Integer.MIN_VALUE
。