0

java.lang.Comparable#compareTo方法规定为第一条

实现者必须确保所有 x 和 y 的 sgn(x.compareTo(y)) == -sgn(y.compare-To(x))。(这意味着当且仅当 y.compareTo(x) 抛出异常时,x.compareTo(y) 必须抛出异常。)

并根据 Joshua Bloch 在 Effective Java 中的第 12 项

这个技巧在这里工作得很好,但应该非常小心地使用。不要使用它,除非您确定所讨论的字段是非负的,或者更一般地说,最低和最高可能字段值之间的差异小于或等于 Integer.MAX_VALUE (231-1)。这个技巧并不总是有效的原因是一个有符号的 32 位整数不足以容纳两个任意有符号的 32 位整数之间的差异。如果 i 是一个大的正整数,而 j 是一个大的负整数,(i - j) 将溢出并返回一个负值。生成的 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来得到那个?任何想法?还是约书亚错了?

4

1 回答 1

3

好吧,这首先违反了一般合同。例如,取value1 = Integer.MIN_VALUEvalue2 = 1。这将Integer.MIN_VALUE > 1有效地报告。

编辑:实际上,我错了 - 很容易违反第一条规定:

int value1 = Integer.MIN_VALUE;
int value2 = 0;

两次比较都会得到否定的结果,因为Integer.MIN_VALUE - 0== 0 - Integer.MIN_VALUE

于 2012-07-26T16:26:39.773 回答