Tengo una lista de puntos donde cada punto es una pequeña lista de tamaño 2 . Quiero ordenar la lista de puntos en orden creciente de x y si los valores de x son iguales, rompo el empate ordenando en orden decreciente de y .
Escribí un comparador personalizado para ordenar los puntos de esta manera:
Collections.sort(points, (a, b) -> { if (a.get(0) != b.get(0)) { return a.get(0) - b.get(0); } return b.get(1) - a.get(1); });Aquí está la entrada antes de ordenar:
(2, 1000) (9, -1000) (3, 15) (9, -15) (5, 12) (12, -12) (5, 10) (10001, -10) (19, 8) (10001, -8)Aquí está el resultado producido después de ordenar con el comparador anterior:
(2, 1000) (3, 15) (5, 12) (5, 10) (9, -15) (9, -1000) (12, -12) (19, 8) (10001, -10) (10001, -8)Observaciones:
x .(5, 12) se puso correctamente antes (5, 10) .(9, -15) se puso correctamente antes (9, -1000) .(10001, -10) se colocó antes de (10001, -8) . Aunque -8 es mayor que -10 . Siento que me estoy perdiendo algo trivial. Experimenté con algunas otras formas de escribir el comparador, como usar Integer.compare(a, b) o simplemente a.compareTo(t) , pero obtuve el mismo resultado.
Finalmente, cambié la representación del punto de List<Integer> a int[] y escribí el mismo comparador nuevamente. Vea los resultados a continuación:
Collections.sort(points, (a, b) -> { if (a[0] != b[0]) return a[0] - b[0]; return b[1] - a[1]; });Entrada antes de ordenar:
(2, 1000) (9, -1000) (3, 15) (9, -150 (5, 12) (12, -12) (5, 10) (10001, -10) (19, 8) (10001, -8)Después de clasificar:
(2, 1000) (3, 15) (5, 12) (5, 10) (9, -15) (9, -1000) (12, -12) (19, 8) (10001, -8) (10001, -10) Entonces, la lista de matrices se ordena correctamente ya que (10001, -8) se colocó correctamente antes de (10001, -10) .
No puedo entender por qué cambiar la representación del punto resolvió el problema y, por lo tanto, esta pregunta. Puedo dar más detalles sobre cómo estoy creando la Lista de puntos si es necesario.
@Alexander Ivanchenko explica muy bien por qué estás viendo el comportamiento que tienes. Una solución al problema es usar Integer.compareTo() :
Collections.sort(points, (a, b) -> { int xCompare = a[0].compareTo(b[0]; if (xCompare != 0) { return xCompare; } retirm a[1].compareTo(b[1]; }); Más allá de esto, sugiero crear una clase Point :
class Point { public int x; public int y; } Aquí uso campos public para seguir el patrón de estructura. Si desea agregar getters y setters y otros comportamientos, siéntase libre de hacerlo. El uso de una clase para representar la estructura de sus datos hace que el código sea más comprensible y fácil de mantener. De hecho, puede implementar fácilmente Comparable en una clase Point o Comparator<Point> .