¿Cuál es la diferencia entre un comparador personalizado y una expresión lambda?
Estaba ordenando una matriz de enteros 2D al hacer una pregunta de Leetcode https://leetcode.com/problems/merge-intervals/
Primero, utilicé un comparador personalizado pero una prueba me arroja “java.lang.IllegalArgumentException: ¡El método de comparación viola su contrato general!”
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] a, int[] b) {
return a[0] > b[0] ? 1 : -1;
}
});
Sin embargo, la expresión lambda a continuación no muestra ninguna excepción:
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
El caso de prueba que falla es algo como esto, pero la longitud de la matriz es mucho mayor:
[[3,4],[1,5],[64,66],[73,77],[90,94],[20,21],[84,87],[48,49],[80,80]]
Estoy muy confundido y agradecería si alguien puede mostrarme la diferencia :)</int[]>
davy.ai
En el primer fragmento de código, estás utilizando un comparador personalizado para ordenar la matriz de enteros 2D llamada
intervals
. Específicamente, estás comparando el primer elemento de cada submatriz utilizando una declaración if-else en línea. Sin embargo, te encontraste con unIllegalArgumentException
con el mensaje “El método de comparación viola su contrato general!”. Esto significa que tu método de comparación está violando uno o más de los tres requisitos para un comparador válido:compare(a,a)
debe devolver 0 para todos los objetosa
.compare(a,b)
devuelve un número entero positivo,compare(b,a)
debe devolver un número entero negativo, y viceversa.compare(a,b)
devuelve un número entero positivo ycompare(b,c)
devuelve un número entero positivo, entoncescompare(a,c)
debe devolver un número entero positivo.Sin ver el caso de prueba que falla, es difícil decir qué requisito viola tu comparador. Sin embargo, un problema posible es que tu comparador no está manejando correctamente los empates. Si dos submatrices tienen el mismo primer elemento, tu comparador devolverá -1 tanto para
compare(a,b)
como paracompare(b,a)
, violando la simetría.En el segundo fragmento de código, estás utilizando una expresión lambda para ordenar
intervals
. La expresión lambda(a, b) -> a[0] - b[0]
es equivalente a la clase interna anónima que utilizaste en el primer fragmento. Sin embargo, las expresiones lambda tienen algunas ventajas sobre las clases internas anónimas, como una sintaxis más concisa y un rendimiento mejorado.No está claro por qué la expresión lambda no causa el
IllegalArgumentException
. Es posible que el caso de prueba que falla esté ejecutando una ruta de código diferente en el métodoArrays.sort
que no es sensible a la violación del contrato.En resumen, la expresión lambda es una forma más moderna y concisa de crear un comparador para ordenar una matriz de enteros 2D, pero no está claro por qué evita el
IllegalArgumentException
que ocurrió con el comparador personalizado.