java.lang.IllegalArgumentException: Comparison method violates its general c
时间: 2023-12-07 20:38:43 浏览: 141
java.lang.IllegalArgumentException: Comparison method violates its general contract是一个常见的异常,通常在使用Java中的排序算法时会出现。这个异常的原因是排序算法的比较器没有遵守Java中的比较器规范,导致排序算法无法正常工作。解决这个问题的方法是检查比较器的实现是否符合规范,具体规范如下:
1. 自反性:对于任意非空引用x,x.equals(x)应该返回true。
2. 对称性:对于任意非空引用x和y,如果x.equals(y)返回true,则y.equals(x)也应该返回true。
3. 传递性:对于任意非空引用x、y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,则x.equals(z)也应该返回true。
4. 一致性:对于任意非空引用x和y,多次调用x.equals(y)应该始终返回true或始终返回false,前提是对象上equals比较中所用的信息没有被修改。
5. 非空性:对于任意非空引用x,x.equals(null)应该返回false。
如果比较器的实现不符合这些规范中的任何一个,就可能会导致java.lang.IllegalArgumentException: Comparison method violates its general contract异常的出现。
相关问题
Caused by: java.lang.IllegalArgumentException: Comparison method violates its general contract! at java.util.TimSort.mergeLo(TimSort.java:777) at java.util.TimSort.mergeAt(TimSort.java:514) at java.util.TimSort.mergeCollapse(TimSort.java:441) at java.util.TimSort.sort(TimSort.java:245) at java.util.Arrays.sort(Arrays.java:1512) at java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:348) at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:500) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:486) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) at com.jcds.app.server.web.core.jcds.problem.impl.JcdsProblemServiceImpl.getRecommendKnowledgeIds(JcdsProblemServiceImpl.java:445) at com.jcds.app.server.web.core.jcds.problem.impl.JcdsProblemServiceImpl.listKnowledgeRecommendVO(JcdsProblemServiceImpl.java:359) at com.jcds.app.server.web.core.jcds.problem.impl.JcdsProblemServiceImpl$$FastClassBySpringCGLIB$$b2971a87.invoke() at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:769) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at
这个错误通常是由于排序算法的比较方法实现不正确引起的。在 Java 中,如果实现了 Comparator 接口的 compare() 方法,必须满足如下三个条件:
1. 自反性:对于所有 x,compare(x, x) == 0。
2. 对称性:对于所有 x 和 y,如果 compare(x, y) > 0,则 compare(y, x) < 0。
3. 传递性:对于所有 x、y 和 z,如果 compare(x, y) > 0 且 compare(y, z) > 0,则 compare(x, z) > 0。
如果这些条件没有被满足,就可能会导致类似于“Comparison method violates its general contract”这样的错误。
要解决这个问题,可以检查比较方法的实现,确保它满足上述三个条件。另外,如果使用了 Java 8 的流式操作和排序方法,也可以尝试使用 sorted() 方法的重载版本:sorted(Comparator.comparing(...).thenComparing(...)),它会同时应用多个比较条件,避免出现违反比较契约的情况。
Collections.sort(slg, (o1,o2) -> { if (ObjectUtil.isNull(o1.get(10))||ObjectUtil.isEmpty(o1.get(10))||ObjectUtil.isNull(o2.get(10))||ObjectUtil.isEmpty(o1.get(10))) { return -1; } String s1 = o1.values().toArray()[10].toString().replaceAll("[^\\u4e00-\\u9fa5]", ""); String s2 = o2.values().toArray()[10].toString().replaceAll("[^\\u4e00-\\u9fa5]", ""); return s1.compareTo(s2); }); java.lang.IllegalArgumentException: Comparison method violates its general contract!
这个错误通常是由于您的比较器实现不符合Java中比较器的约定所导致的。具体来说,您的比较器实现中存在如下问题:
1. 比较器实现不满足自反性,因为对于某些元素,比较器返回-1,但是对于这些元素本身来说,它们是相等的,即o1和o2相等。
2. 比较器实现不满足传递性,因为对于某些元素,比较器可能返回-1或1,但是这些元素实际上是相等的,即o1和o2相等。
要解决这个问题,您需要修改比较器的实现,以满足Java中比较器的约定。具体来说,您可以按照以下步骤进行修改:
1. 在比较器中添加一个判断,如果两个元素相等,则返回0。
2. 在比较器中添加一个判断,如果两个元素不相等,则返回它们之间的比较结果。
3. 将比较器的实现改为只比较o1和o2中第10个值中的中文部分,而不是整个字符串。这可以使用正则表达式来实现。
修改后的代码如下所示:
```
Collections.sort(slg, (o1, o2) -> {
if (ObjectUtil.isNull(o1.get(10)) || ObjectUtil.isEmpty(o1.get(10)) || ObjectUtil.isNull(o2.get(10)) || ObjectUtil.isEmpty(o2.get(10))) {
return -1;
}
String s1 = o1.values().toArray()[10].toString().replaceAll("[^\\u4e00-\\u9fa5]", "");
String s2 = o2.values().toArray()[10].toString().replaceAll("[^\\u4e00-\\u9fa5]", "");
if (s1.equals(s2)) {
return 0;
} else {
return s1.compareTo(s2);
}
});
```
希望能帮到您!
阅读全文