Hola,
se debe a que no has completado el método
compareTo()Verás, el TreeSet tiene una peculiaridad y es que SOLO admite elementos que NO estén repetidos.
Pero claro, él por si solo, no es capaz de discernir cuándo un elemento se repite o no.
En este caso trabajamos con objetos Jugador., ¿Cuándo un Jugador es igual a otro?
¿Cuando tienen el mismo nombre?
¿Cuando tiene el mismo ID?
¿Cuando coinciden tanto el nombre como el ID?
Esto TreeSet no lo puede decidir, lo decide el programador
Una forma de hacerlo, es
implementando la interfaz Comparable a la clase que está creando.
A Jugador, le has implementado dicha interfaz, bién, pero no has completado el método
compareTo().
Así que no has decidido todavía cómo se han de comparar los objetos Jugador.
Has dejado el código que viene por defecto, que hace un return 0.
@Override
public int compareTo(Jugador o) {
// TODO Auto-generated method stub
return 0;
}
Y cuando
compareTo() retorna 0, significa que los objetos que se comparan
son iguales.Por tanto, el TreeSet confía ciegamente en lo que este método le dice, y le está diciendo que todos los objetos Jugador que le estás pasando, son iguales.
Y por tanto, el TreeSet solo admite el primero y el resto los rechaza.
Esto se puede comprobar muy fácilmente. Cuando añadimos un objeto al TreeSet, este retorna true si lo admite o false si lo rechaza.
Si pedimos mostrar en pantalla qué es lo que retorna cada vez que hacemos un add()...
public static void main(String[] args) {
TreeSet <Jugador> listaJugadores = new TreeSet<Jugador>();
Jugador j1 = new Jugador("jA","pepe");
Jugador j2 = new Jugador("jB","juan");
Jugador j3 = new Jugador("jC","maria");
System.out.println(listaJugadores.add(j1));
System.out.println(listaJugadores.add(j2));
System.out.println(listaJugadores.add(j3));
for(Jugador j: listaJugadores) {
j.mostrarDatos();
}
}
...veremos que solo admite el primero:
true
false
false
ID: jA
Nombre: pepe
Podemos hacer otro experimento, cambiamos el método
compareTo() para que retorne algo que no sea 0:
@Override
public int compareTo(Jugador o) {
// TODO Auto-generated method stub
return 1;
}
Cuando retorna un entero positivo, como el 1, significa que el objeto que recibe como argumento para compararse,
es mayor. Por tanto, no son iguales, así que ahora TreeSet si admitirá los tres objetos que le pasamos (aunque en realidad aún no hemos establecido una regla de comparación que sea útil)
Si volvemos a ejecutar el programa, veremos que los tres objetos añadidos retornan true y podemos listarlos en pantalla:
true
true
true
ID: jA
Nombre: pepe
ID: jB
Nombre: juan
ID: jC
Nombre: maria
Aprovechemos la ocasión para hacer otro experimento. Volvemos a cambiar el retorno de
compareTo(), esta vez, vamos a pedir que retorne un valor negativo.
@Override
public int compareTo(Jugador o) {
// TODO Auto-generated method stub
return -1;
}
Un valor negativo significa que el objeto que recibe como argumento para compararse,
es menor.
¿Qué pasa entonces si volvemos a ejecutar el programa?
true
true
true
ID: jC
Nombre: maria
ID: jB
Nombre: juan
ID: jA
Nombre: pepe
¡¡Voilá!!
Los tres Jugadores se han añadido y además se han ordenado de forma inversa a la que los hemos insertado.
Esto es porque ahora
compareTo() le está diciendo a TreeSet que todas las comparaciones resultan en que el nuevo objeto recibido es menor respecto a los que ya hay insertados.
Esta es otra peculiaridad de TreeSet, no solo evita que se repitan elementos, si no que siempre los tiene ordenados de menor a mayor.
La verdad es que este tipo de Set es un encanto
je je.
Pero claro, para que lo haga bien, nosotros tenemos que escribir correctamente el método
compareTo() y decidir cuáles son las reglas de comparación para nuestra clase.
La pregunta es:
¿Cuándo podemos considerar un Jugador menor o mayor que otro?Puede depende de cada caso y del criterio del programador, por supuesto..
En este caso, comos los jugadores tienen un ID, que se supone ha de ser único, pues puede ser ese el atributo que consideremos fundamental para comparar Jugadores.
Ahora hay que escribir un código para decidir como compara ese atributo.
Puesto que se trata de un String, y la clase String ya tiene implementada su propia regla de comparación, pues podemos simplemente establecer que se retorne el resultado de comparar los ID, tal cuál establece la clase String:
@Override
public int compareTo(Jugador o) {
return this.id.compareTo(o.id);
}
Los String hacen una comparación lexicográfica, es decir, que la letra a se considera menor que la b, la b es menor que la c, etc..
Vamos, que ordena alfabéticamente de la a a la z, y según cuantas letras tiene cada String.
Si volvemos a ejecutar el programa, y cambiamos los id para insertarlos
desordenados alfabéticamente:
public static void main(String[] args) {
TreeSet <Jugador> listaJugadores = new TreeSet<Jugador>();
Jugador j1 = new Jugador("jB","pepe");
Jugador j2 = new Jugador("jC","juan");
Jugador j3 = new Jugador("jA","maria");
System.out.println(listaJugadores.add(j1));
System.out.println(listaJugadores.add(j2));
System.out.println(listaJugadores.add(j3));
for(Jugador j: listaJugadores) {
j.mostrarDatos();
}
}
Veremos que al mostrarlos, se muestran bien ordenados:
true
true
true
ID: jA
Nombre: maria
ID: jB
Nombre: pepe
ID: jC
Nombre: juan