比较器不工作
Comparator not working
我们编写了以下代码,但不适用于 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()
方法 return 是一个整数值。
以下代码运行良好
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]
您忘记 return 0 表示相等的值。
以下对于非空 x 始终为真:
(x < x ? 1 : -1) == -1
您的初始实现在两种类型相等时未正确处理(即返回 0),因此违反了 Comparator
的一般合同。
与其尝试自己实现两个整数之间的比较逻辑,不如让Integer
做what it knows best?
return Integer.compare(a.getType(), b.getType());
你的两个比较器不一样,它们实际上是相反的。
在第一种情况下,如果 a
较小,您 return 一个 正值 。
其次,如果 a
较小,您 return 一个 负值 。
您可以尝试下面的代码,它会考虑它们是否相等,而这不会。如果它们相等或 b 大于 a,它将 return -1。所以试试...
return a.getType() < b.getType()? -1 : a.getType() > b.getType()? 1 : 0;
在此测试a是否小于b,如果是,则returns -1,如果不是,则测试a是否大于b,如果为真则returns 1,如果不是,它们必须相等,所以 returns 0;
当然,您可以将这些值更改为适合您的值。
我们编写了以下代码,但不适用于 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()
方法 return 是一个整数值。
以下代码运行良好
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]
您忘记 return 0 表示相等的值。
以下对于非空 x 始终为真:
(x < x ? 1 : -1) == -1
您的初始实现在两种类型相等时未正确处理(即返回 0),因此违反了 Comparator
的一般合同。
与其尝试自己实现两个整数之间的比较逻辑,不如让Integer
做what it knows best?
return Integer.compare(a.getType(), b.getType());
你的两个比较器不一样,它们实际上是相反的。
在第一种情况下,如果 a
较小,您 return 一个 正值 。
其次,如果 a
较小,您 return 一个 负值 。
您可以尝试下面的代码,它会考虑它们是否相等,而这不会。如果它们相等或 b 大于 a,它将 return -1。所以试试...
return a.getType() < b.getType()? -1 : a.getType() > b.getType()? 1 : 0;
在此测试a是否小于b,如果是,则returns -1,如果不是,则测试a是否大于b,如果为真则returns 1,如果不是,它们必须相等,所以 returns 0;
当然,您可以将这些值更改为适合您的值。