我们编写了以下代码,这些代码不适用于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]
答案 0 :(得分:7)
当两种类型相等时,您的初始实现违反了Comparator
的一般合同,因为它没有正确处理(即返回0)。
为什么不让Integer
做what 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;
当然,您可以将这些值更改为适合您的任何值。