Java中可比较<t>的异常现象</t>

时间:2013-04-16 13:19:22

标签: java comparable

当我写一个实现RankedObject的{​​{1}}类时:

Comparable<RankedObject>

我想在整体上按升序排列RankedObject&#34;同时,public static class RankedObj implements Comparable<RankedObj> { int i; public RankedObj(int i) { this.i=i; } @Override public String toString() { return "RankedObj [i=" + i + "]"; } @Override public int compareTo(RankedObj o) { if(this.i == 3) { // '3' will always be the smallest item return -1; } return this.i-o.i; } 始终为3一个&#34;。在测试时,我发现原始列表的顺序确实会影响结果,并且在某些情况下结果不正确。即:

smallest

有谁可以告诉我为什么?以及如何在整个过程中实现按升序排列列表的目的。&#39; 3&#39;是最小的项目?非常感谢!

P.S。根据我使用//----CASE 1---- List<RankedObj> list = new ArrayList<>(); list.add(new RankedObj(11)); list.add(new RankedObj(1)); list.add(new RankedObj(12)); list.add(new RankedObj(3)); list.add(new RankedObj(8)); Collections.sort(list); System.out.println(list); //output (as I intend) [RankedObj [i=3], RankedObj [i=1], RankedObj [i=8], RankedObj [i=11], RankedObj [i=12]] //----CASE 2---- List<RankedObj> list = new ArrayList<>(); list.add(new RankedObj(11)); list.add(new RankedObj(12)); list.add(new RankedObj(3)); list.add(new RankedObj(8)); list.add(new RankedObj(1)); Collections.sort(list); System.out.println(list); //output (not what my Comparable intends) [RankedObj [i=1], RankedObj [i=3], RankedObj [i=8], RankedObj [i=11], RankedObj [i=12]] 的测试,其中代码与Comparator中的代码相同,结果相同:

Comparable

2 个答案:

答案 0 :(得分:3)

您的比较不对称。

考虑这两个电话:

RankedObj x = new RankedObj(1);
RankedObj y = new RankedObj(3);
System.out.println(x.compareTo(y)); // -2
System.out.println(y.compareTo(x)); // -1

他们 应该给出0的答案,或给出相反符号的答案。相反,他们都会返回一个负值 - 因为在第一次调用中,o1.i是1(而不是3)所以它会回落到o1.i - o2.i - 这仍然是负数。

此外,您还有一个问题,即如果您有一个非常强的负值,当您从中减去一个强正值时,减法将会溢出。

您需要将其修复为对称​​和以避免溢出。这应该这样做:

@Override
public int compareTo(RankedObj o) {
    // Handle equality first
    if (this.i == o.i) {
        return 0;
    }
    // Handle the magic value correctly on *both* sides
    if(this.i == 3) {
        return -1;
    }
    if (o.i == 3) {
        return 1;
    }
    // Fall back to normal comparsions
    return Integer.compare(i, o.i);
}

答案 1 :(得分:2)

尝试:

@Override
public int compare(RankedObj o1, RankedObj o2) {
    if(o1.i == o2.i){       {
        return 0;
    } else if(o1.i == 3)       {
        return -1;
    } else if (o2.i == 3){
        return 1;
    }
return o1.i-o2.i;
}

该实现假设您只使用从另一个值中减去一个值时不会导致溢出的小数字。