Publi

Ordenando listas en Java [ Comparables y Comparator ]

Imaginemos que tenemos una lista de objetos (String) y los queremos ordenar por orden alfabético. Lo podemos hacer con Collections.sort() de la siguiente manera:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.*;

public class Main
{
    public static void main(String [] args)
    {
    List<String> lista = new ArrayList<String>();
    lista.add("Maleta");
    lista.add("Muñequera");
    lista.add("Póster");
    lista.add("Tarjeta");
    lista.add("Post-it");
    lista.add("Teléfono");
    lista.add("Lámpara");
    lista.add("Auriculares");

    Collections.sort(lista);

    for (String l: lista) {
        System.out.println(l);
    }
    }
}

Ahora bien, necesitamos ahora un tipo complejo de información donde almacenaremos muchos más datos, por ejemplo, los jugadores de un equipo de fútbol. Aunque cuando llamemos a sort, no va a tener ni idea de cómo comparar dos jugadores de fútbol (en el ejemplo sólo tienen datos de nombre, posición y goles (puestos al azar)), y queremos ordenarlos por posición, y si la posición es la misma, por nombre. Tenemos que implementar un Comparable:

Jugador.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class Jugador implements Comparable<Jugador>
{
    private String nombre;
    private int posicion;
    private int goles;

    public static final int PORTERO = 0;
    public static final int DEFENSA = 1;
    public static final int CENTROCAMPISTA = 2;
    public static final int DELANTERO = 3;

    private String[] posiciones = new String[] {"Portero","Defensa", "Centrocampista", "Delantero"};

    public Jugador(String nombre, int posicion, int goles)
    {
    this.nombre = nombre;
    this.posicion=posicion;
    this.goles=goles;
    }

    public String toString()
    {
    return nombre+": "+this.posiciones[posicion]+" ha marcado "+goles+" goles";
    }

    public int compareTo(Jugador j)
    {
    if (this.posicion==j.posicion)
        return j.nombre.compareTo(this.nombre);
    else
        return this.posicion-j.posicion;
    }
}

Main.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.util.*;

public class Main2
{
    public static void main(String [] args)
    {
    List<Jugador> lista = new ArrayList<Jugador>();
    lista.add(new Jugador("Iker Casillas", Jugador.PORTERO,3));
    lista.add(new Jugador("Jesús Navas", Jugador.DELANTERO,10));
    lista.add(new Jugador("Xabi Alonso", Jugador.CENTROCAMPISTA,4));
    lista.add(new Jugador("Sergio Ramos", Jugador.DEFENSA,2));
    lista.add(new Jugador("Álvaro Arbeloa", Jugador.DEFENSA,1));
    lista.add(new Jugador("Andrés Iniesta", Jugador.CENTROCAMPISTA, 12));
    lista.add(new Jugador("David Villa", Jugador.DELANTERO,15));
    lista.add(new Jugador("Fernando Torres", Jugador.DELANTERO,2));
    lista.add(new Jugador("José Manuel Reina", Jugador.PORTERO, 1));
    lista.add(new Jugador("Roberto Soldado", Jugador.DELANTERO,12));
    lista.add(new Jugador("Santiago Cazorla", Jugador.CENTROCAMPISTA,5));
    lista.add(new Jugador("Jordi Alba", Jugador.DEFENSA,2));
    lista.add(new Jugador("Cesc Fábregas", Jugador.CENTROCAMPISTA,4));

    Collections.sort(lista);

    for (Jugador l: lista) {
        System.out.println(l);
    }
    }
}

Por ejemplo, si queremos ordenar en orden inverso podemos hacer:

1
    Collections.sort(lista, Collections.reverseOrder());

Hemos visto que la entrada de jugadores es desordenada, y cuando llamamos a Collections.sort(), éste hará uso del método compareTo() del Comparable() para realizar la ordenación, pero tal vez queramos introducir varios métodos de ordenación, por la posición, por el nombre y por el número de goles marcados. Para ello añadimos a la clase jugador lo siguiente:

1
2
3
4
5
6
7
8
9
10
11
    public static Comparator<Jugador> JugadorGolesComparator = new Comparator<Jugador>() {
   
        public int compare(Jugador j1, Jugador j2) {
       
        if (j1.goles==j2.goles)
            return j1.nombre.compareTo(j2.nombre);
       
        return j1.goles-j2.goles;
        }
 
    };

Y en el Main podemos hacer:

1
    Collections.sort(lista, Jugador.JugadorGolesComparator);

donde decimos que ése sea el comparador que queremos utilizar. Ahora bien, si queremos darle la vuelta a la ordenación podemos utilizar

1
    Collections.reverse(lista);

También podría interesarte...

There are 2 comments left Ir a comentario

  1. Pingback: Bitacoras.com /

  2. Pingback: BlogESfera.com /

Leave a Reply