Java 比较器不工作

Java 比较器不工作,java,comparator,Java,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 :

我们已经编写了以下代码,它不适用于
比较器
比较方法

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;
}
若我们删除了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]

您忘记了为相等的值返回0

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

(x < x ? 1 : -1) == -1
(x
您忘记了为相等的值返回0

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

(x < x ? 1 : -1) == -1
(x
当两种类型相等时,您的初始实现未正确处理(即返回0),从而违反了s的一般约定

与其自己尝试实现两个整数之间的比较逻辑,为什么不让
Integer
do呢


当两种类型相等时,您的初始实现没有正确处理(即返回0),从而打破了s的一般约定

与其自己尝试实现两个整数之间的比较逻辑,为什么不让
Integer
do呢


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

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


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

两个比较器不相同,它们实际上是相反的

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


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

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

返回a.getType()b.getType()?1 : 0;

在这种情况下,它测试a是否小于b,如果是,它返回-1,如果不是,它然后测试a是否大于b,如果是真的,它返回1,如果不是,它们必须相等,因此它返回0


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

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

返回a.getType()b.getType()?1 : 0;

在这种情况下,它测试a是否小于b,如果是,它返回-1,如果不是,它然后测试a是否大于b,如果是真的,它返回1,如果不是,它们必须相等,因此它返回0



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

您会遇到什么错误?什么是MailObject类?为什么需要使用三元运算符?为什么不显式键入比较器?!在第一种方法中,您只处理大于和小于,而不处理相等的情况,所以这是一个简单的类对象。包含简单属性的。出现了什么错误?什么是MailObject类?为什么需要使用三元运算符?为什么不显式键入比较器?!在第一种方法中,您只处理大于和小于,而不处理相等的情况,所以这是一个简单的类对象。它包含简单属性。假设
a.getType
返回
int
a.getType()-b.getType()
如果结果相等,将返回0。有问题的三元运算符如何?假设
a.getType
返回
int
a.getType()-b.getType()
如果它们的结果相等,将返回0。有问题的三元运算符呢?我们可以用这样的方法来处理可为null的参数吗?您能解释一下Comparator接口和我们的实现之间的基本契约吗。@在Java 7及以下版本中,我只显式地处理
null
s,就像OP一样。在Java 8和更高版本中,使用
Comparator.nullsFirst
Comparator.nullsLast
@VinaySharma时,有一些语法上的甜点
Comparator#compare
的一般约定是如果第一个参数先到,则返回一个负值,如果第二个参数应排在第一位,则为正值;如果它们“相等”,则为0。在您的实现中,当您试图按
getType()
进行排序时,如果两个对象都为此方法返回相同的值,则不会返回0。对于可为null的参数,我们可以使用类似的方法吗?您能解释一下Comparator接口和我们的实现之间的基本约定吗。@Java 7及以下版本中的Basilevs,我只需要显式地处理
null
s,就像OP一样。在Java 8和更高版本中,使用
Comparator.nullsFirst
Comparator.nullsLast
@VinaySharma时,有一些语法上的甜点
Comparator#compare
的一般约定是如果第一个参数先到,则返回一个负值,如果第二个参数应排在第一位,则为正值;如果它们“相等”,则为0。在您的实现中,如果您试图按
getType()
进行排序,那么如果两个对象都为此方法返回相同的值,则不会返回0。
return Integer.compare(a.getType(), b.getType());