比较者无法工作

时间:2015-12-17 05:28:14

标签: java comparator

我们编写了以下代码,这些代码不适用于Comparator比较方法。

public int compare(Object o1, Object o2)
{
    if (o2 == null) return 1;
    else if (o1 == null) return -1;

    MailObject a = (MailObject)o1;
    MailObject b = (MailObject)o2;
    return a.getType() < b.getType()? 1 : -1;
}

其中getType()方法返回一个整数值。 以下代码工作正常

public int compare(Object o1, Object o2)
{
    if (o2 == null) return 1;
    else if (o1 == null) return -1;

    MailObject a = (MailObject)o1;
    MailObject b = (MailObject)o2;
    return a.getType() - b.getType();
}

如果我们在return语句中删除三元运算符,那么它运行正常。如果我们添加相同的检查,那么它也工作正常。为什么呢?

第一个代码块,给出以下异常:

07:45:22 ERROR c.c.servlet.MyServlet - Comparison method violates its general contract!
java.lang.IllegalArgumentException: Comparison method violates its general contract!
               at java.util.TimSort.mergeHi(Unknown Source) ~[na:1.8.0_25]
               at java.util.TimSort.mergeAt(Unknown Source) ~[na:1.8.0_25]
               at java.util.TimSort.mergeCollapse(Unknown Source) ~[na:1.8.0_25]
               at java.util.TimSort.sort(Unknown Source) ~[na:1.8.0_25]
               at java.util.Arrays.sort(Unknown Source) ~[na:1.8.0_25]
               at java.util.List.sort(Unknown Source) ~[na:1.8.0_25]
               at java.util.Collections.sort(Unknown Source) ~[na:1.8.0_25]

4 个答案:

答案 0 :(得分:7)

当两种类型相等时,您的初始实现违反了Comparator的一般合同,因为它没有正确处理(即返回0)。

为什么不让Integerwhat it knows best,而不是试图在两个整数之间实现比较逻辑呢?

return Integer.compare(a.getType(), b.getType());

答案 1 :(得分:0)

您忘记返回0表示相等的值。

以下对于非空x始终为真:

libprotobuf.so

答案 2 :(得分:0)

你的两个比较器都不一样,它们实际上是相反的。

在第一种情况下,如果a较小,则返回正值

第二,如果a较小,则返回负值

答案 3 :(得分:0)

您可以尝试以下代码,如果它们相等则会考虑这些代码,但这不会。如果它们相等或b大于a,它将返回-1。所以试试......

返回a.getType()&lt; b.getType()? -1:a.getType()&gt; b.getType()? 1:0;

在此测试a是否小于b,如果是,则返回-1,如果不是,则测试a是否大于b,如果是,则返回1,否则返回1是相等的,所以它返回0;

当然,您可以将这些值更改为适合您的任何值。