He estado observando la diferencia entre Collections.sort
y list.sort
, específicamente con respecto al uso de Comparator
métodos estáticos y si se requieren tipos de parámetros en las expresiones lambda. Antes de comenzar, sé que podría usar referencias de métodos, por ejemplo, Song::getTitle
para superar mis problemas, pero mi consulta aquí no es tanto algo que quiero arreglar sino algo a lo que quiero una respuesta, es decir, ¿por qué el compilador de Java lo maneja de esta manera? .
Estos son mis hallazgos. Supongamos que tenemos un ArrayList
tipo de Song
, con algunas canciones agregadas, hay 3 métodos de obtención estándar:
ArrayList<Song> playlist1 = new ArrayList<Song>();
//add some new Song objects
playlist.addSong( new Song("Only Girl (In The World)", 235, "Rhianna") );
playlist.addSong( new Song("Thinking of Me", 206, "Olly Murs") );
playlist.addSong( new Song("Raise Your Glass", 202,"P!nk") );
Aquí hay una llamada a ambos tipos de método de clasificación que funciona, no hay problema:
Collections.sort(playlist1,
Comparator.comparing(p1 -> p1.getTitle()));
playlist1.sort(
Comparator.comparing(p1 -> p1.getTitle()));
Tan pronto como empiezo a encadenar thenComparing
, sucede lo siguiente:
Collections.sort(playlist1,
Comparator.comparing(p1 -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
playlist1.sort(
Comparator.comparing(p1 -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
es decir, errores de sintaxis porque ya no conoce el tipo de p1
. Entonces, para solucionar esto, agrego el tipo Song
al primer parámetro (de comparación):
Collections.sort(playlist1,
Comparator.comparing((Song p1) -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
playlist1.sort(
Comparator.comparing((Song p1) -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
Ahora aquí viene la parte CONFUSA. Para p laylist1.sort
, es decir, la Lista, esto resuelve todos los errores de compilación, para las dos thenComparing
llamadas siguientes . Sin embargo, Collections.sort
lo resuelve para el primero, pero no para el último. Probé, agregué varias llamadas adicionales thenComparing
y siempre muestra un error para la última, a menos que puse (Song p1)
el parámetro.
Ahora continué probando esto con la creación de un TreeSet
y con el uso Objects.compare
:
int x = Objects.compare(t1, t2,
Comparator.comparing((Song p1) -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
Set<Song> set = new TreeSet<Song>(
Comparator.comparing((Song p1) -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
Ocurre lo mismo que en, para el TreeSet
, no hay errores de compilación pero para Objects.compare
la última llamada a thenComparing
muestra un error.
¿Alguien puede explicar por qué está sucediendo esto y también por qué no es necesario usar (Song p1)
nada cuando simplemente se llama al método de comparación (sin más thenComparing
llamadas)?
Otra consulta sobre el mismo tema es cuando hago esto con TreeSet
:
Set<Song> set = new TreeSet<Song>(
Comparator.comparing(p1 -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
es decir, elimine el tipo Song
del primer parámetro lambda para la llamada al método de comparación, muestra errores de sintaxis bajo la llamada a comparar y la primera llamada a, thenComparing
pero no a la llamada final thenComparing
, ¡casi lo contrario de lo que estaba sucediendo arriba! Considerando que, para los otros 3 ejemplos, es decir Objects.compare
, con List.sort
y Collections.sort
cuando elimino ese primer Song
tipo de parámetro, muestra errores de sintaxis para todas las llamadas.
Muchas gracias de antemano.
Editado para incluir una captura de pantalla de los errores que recibía en Eclipse Kepler SR2, que desde entonces he descubierto que son específicos de Eclipse porque cuando se compila con el compilador java JDK8 en la línea de comandos, se compila correctamente.