我有一个课程,我已将其简化为:

final class Thing {
    private final int value;
    public Thing(int value) {
        this.value = value;
    }
    public int getValue() {
        return value;
    }
    @Override public String toString() {
        return Integer.toString(value);
    }
}

我想对这个东西的数组进行排序。所以我创建了一个简单的copmarator:

private static final Comparator<Thing> reverse = new Comparator<Thing>() {
    public int compare(Thing a, Thing b) {
        return a.getValue() - b.getValue();
    }
};

然后我使用 Arrays.sort 的两个参数形式。

这适用于我的测试用例,但有时它会以一个奇怪但可重复的顺序结束。 怎么会这样?

有帮助吗?

解决方案

整数溢出&#8230;或者更准确地说,是下溢。

相反,做一个明确的比较:

private static final Comparator<Thing> reverse = new Comparator<Thing>() {
    public int compare(Thing a, Thing b) {
      int av = a.getValue(), bv = b.getValue();
      return (av == bv) ? 0 : ((av < bv) ? -1 : +1);
    }
};

如果您确定差异不会“环绕”,则使用减法就可以了。例如,当有问题的数据被限制为非负数时。

其他提示

您无法使用减号来创建比较。当绝对差值超过 Integer.MAX_VALUE

时,您将溢出

相反,请使用此算法:

int compareInts( int x, int y ) {
  if ( x < y ) return -1;
  if ( x > y ) return 1;
  return 0;
}

我喜欢在图书馆中使用此功能来实现此目的。

System.out.println(Integer.MAX_Value - Integer.MIN_VALUE);

这需要返回正数,如MAX_VALUE&gt; MIN_VALUE但是打印-1

在比较Java原语时,建议将它们转换为Object对象并依赖它们的 compareTo()方法。

在这种情况下,你可以这样做:

return Integer.valueOf(a.getValue()).compareTo(b.getValue())

如有疑问,请使用经过充分测试的图书馆。

你扔在那里的是什么数字?如果你的数字足够大,你可以用整数的MIN / MAX值换行,最后就会搞得一团糟。

如果a的值非常负,且b的值非常正,则答案将非常错误。

IIRC,Int溢出在JVM中无声地环绕

- MarkusQ

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top