异常
java.lang.IllegalArgumentException: ¡El método de comparación viola su contrato general!
en java.util.TimSort.mergeHi (fuente desconocida)
Que se basa en https://www.cnblogs.com/firstdream/p/7204067.html
Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(Unknown Source)
at java.util.TimSort.mergeAt(Unknown Source)
at java.util.TimSort.mergeForceCollapse(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at com.fc.test.sort(test.java:193)
at com.fc.test.main(test.java:165)
Es la razón del JDK
la razón
En la implementación del método Collections.Sort en JDK7, si los dos valores son iguales, el método de comparación debe devolver 0; de lo contrario, se puede producir un error al ordenar, pero JDK6 no tiene esta restricción.
Por encima de JDK7, Comparator debe satisfacer la reflexividad, la transitividad y la simetría; de lo contrario, Arrays.sort,
Collections.sort informará IllegalArgumentException.
Descripción:
1) Reflexividad: El resultado de la comparación de xey es opuesto al resultado de la comparación de y y x.
2) Transitividad: x> y, y> z, luego x> z.
3) Simetría: x = y, entonces el resultado de la comparación de x, z es el mismo que el resultado de la comparación de y, z.
Contraejemplo: el siguiente ejemplo no se ocupa del caso de igualdad y puede producirse una excepción en el uso real: la operación ternaria no se puede utilizar
new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getId() > o2.getId() ? 1 : -1;
}
}
Solucion uno
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// return o1 > o2 ? 1 : -1;
return o1.compareTo(o2);// 正确的方式
}
});
Solución 2:
No modifiques el código
Entonces el problema está llegando. ¿Por qué el código anterior se ejecuta sin problemas en JDK6, pero arroja una excepción en JDK7? Esto se debe a que el algoritmo de clasificación subyacente de JDK7 ha cambiado. Si desea continuar utilizando el algoritmo de clasificación de JDK6, puede agregar los siguientes parámetros a los parámetros de inicio de la JVM:
-Djava.util.Arrays.useLegacyMergeSort=true
De esta forma, el algoritmo de ordenación JDK6 se utilizará como de costumbre, y el problema de compatibilidad se solucionará cuando no se pueda modificar el código.