Ordenar un ArrayList en Java


El proyecto de este post lo puedes descargar pulsando AQUI.

Una de las funcionalidades más interesantes a la hora de trabajar con estructuras de datos tipo "pila", "cola", "lista" etc. es su ordenación. En el post de "Ordenar Arrays en Java (Con sus indices)" implementamos un API que nos permitía ordenar Arrays y sus indices, que es una funcionalidad muy importante que no ha sido implementada por ningún API conocida y de forma sencilla.

En este post vamos a mostrar como ordenar ArrayList, bien sea con un ArrayList de datos atómicos o con un ArrayList de objetos.

Para realizar estas operaciones necesitaremos trabajar con la Clase "Collections" de Java. No vamos a explicar las características de esta clase, sino que simplemente vamos a utilizarla para ordenar ArrayList's. Como suele ser habitual en esta web, pasamos a mostrar esta funcionalidad con un ejemplo:

Vamos a tener un ArrayList llamado "arrayListInt" que es un array de enteros y que le pondremos los siguientes valores (sino sabéis el método add, mirar el post "ArrayList en Java, con ejemplos"):

private static ArrayList arrayListInt = new ArrayList<>();

	// Guardo datos en el ArrayList
	arrayListInt.add(3); 	arrayListInt.add(4);
	arrayListInt.add(2);	arrayListInt.add(6);
	arrayListInt.add(5);	arrayListInt.add(1);
	arrayListInt.add(7);

Si imprimimos este ArrayList en el orden en el que hemos guardado los elementos, tendremos que el primer elemento sera el numeró '3', el segundo el número '6' y si seguimos el orden, el último será el número '7'.

Para ordenar este ArrayList de menor a mayor, vamos a utilizar el método "sort" de la clase Collections:

Collections.sort(arrayListInt);

Con este método nos devolverá el ArrayList ordenado de menor a mayor, siendo la salida la siguiente (en el proyecto que os podéis descargar, podéis ver los método que imprimen por pantalla los ArrayList):

Posicion(1) = 1
Posicion(2) = 2
Posicion(3) = 3
Posicion(4) = 4
Posicion(5) = 5
Posicion(6) = 6
Posicion(7) = 7

Para ordenarlo de mayor a menor, tenemos que crearnos un objeto de la clase Comparator para que compare los elementos y los ponga en orden inverso. Esto lo hacemos de la siguiente manera:

Comparator<Integer> comparador = Collections.reverseOrder();
Collections.sort(arrayListInt, comparador);

Ejecutando esta parte del programa e imprimiendo por pantalla el ArrayList resultante, tenemos el ArrayList ordenado de mayor a menor:

Posicion(1) = 7
Posicion(2) = 6
Posicion(3) = 5
Posicion(4) = 4
Posicion(5) = 3
Posicion(6) = 2
Posicion(7) = 1

Pero ¿Que pasa si lo que tenemos es un ArrayList de objetos de una determinada clase y lo que queremos ordenar ese ArrayList por el valor de un determinado atributo?. Bueno pues hay una sencilla solución que vamos a mostrar a continuación y que consiste en sobreescribir un método de la clase Comparator.
Supongamos que tenemos una clase "Persona" de la siguiente forma:

class Persona {

	private String nombre;
	private int edad;

	public Persona() {
	}

	public Persona(String nombre, int edad) {
		this.nombre = nombre;
		this.edad = edad;
	}

	public String getNombre() {
		return nombre;
	}

	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	public int getEdad() {
		return edad;
	}

	public void setEdad(int edad) {
		this.edad = edad;
	}

	@Override
	public String toString() {
		return this.getNombre() + "  -  " + this.getEdad();
	}
}

Supongamos que tenemos un ArrayList llamado "personas" con los siguientes objetos de la clase persona:

private static ArrayList personas = new ArrayList<>();
................
................
personas.add(new Persona("Pepe", 28));
personas.add(new Persona("Juan", 32));
personas.add(new Persona("Paco", 40));
personas.add(new Persona("Susi", 24));
personas.add(new Persona("Lola", 20));
personas.add(new Persona("Jose", 28));
personas.add(new Persona("Dani", 24));
personas.add(new Persona("Sara", 36));

Este ArrayList lo queremos ordenar (de menor a mayor edad) en función de la edad de las personas, por tanto tenemos que sobre escribir el método "compare" de la clase Comparator y llamar al método "sort" de la clase collections. Esto lo hacemos de la siguiente forma:

Collections.sort(personas, new Comparator() {
	@Override
	public int compare(Persona p1, Persona p2) {
		return new Integer(p1.getEdad()).compareTo(new Integer(p2.getEdad()));
	}
});

Como vemos lo que hace el método "compare" es comparar dos edades dadas. En este caso estamos comparando dos atributos de tipo "Integer". Si lo queremos hacer con un String, Double, etc. solo tenemos que cambiar el tipo de dato. Como salida a este código tenemos lo siguiente:

Posicion(1) = Lola  -  20
Posicion(2) = Dani  -  24
Posicion(3) = Susi  -  24
Posicion(4) = Pepe  -  28
Posicion(5) = Jose  -  28
Posicion(6) = Juan  -  32
Posicion(7) = Sara  -  36
Posicion(8) = Paco  -  40

Si ahora queremos ordenarlo de mayor a menor edad, solo tenemos que cambiar el método "compare" poniendo la comparación al revés:

Collections.sort(personas, new Comparator() {
	@Override
	public int compare(Persona p1, Persona p2) {
		// Aqui esta el truco, ahora comparamos p2 con p1 y no al reves como antes
		return new Integer(p2.getEdad()).compareTo(new Integer(p1.getEdad()));
	}
});

Como resultado de esta ordenación obtenemos lo siguiente:

Posicion(1) = Paco  -  40
Posicion(2) = Sara  -  36
Posicion(3) = Juan  -  32
Posicion(4) = Pepe  -  28
Posicion(5) = Jose  -  28
Posicion(6) = Dani  -  24
Posicion(7) = Susi  -  24
Posicion(8) = Lola  -  20

Esto es en resumen todo lo necesario para ordenar ArrayList, bien sean por un atributo de una serie de objetos o con datos atómicos (en realidad son objetos que representan datos atómicos, Integer, Double, etc.). No hemos entrado en detalle de explicar las clases Comparator y Collections ya que en principio la finalidad de este post es la de dar una solución a la ordenación de ArrayList.

Comparte esta entrada en:
Safe Creative #1401310112503
Ordenar un ArrayList en Java por "www.jarroba.com" esta bajo una licencia Creative Commons
Reconocimiento-NoComercial-CompartirIgual 3.0 Unported License.
Creado a partir de la obra en www.jarroba.com

45 comentarios en “Ordenar un ArrayList en Java”

  1. Hola paraordenar de mayor a menor no hace falta el comparatorse puede hacer mas facil

    //se ordenan

    Collections.sort(numeros);

    // se invierte el orden

    Collections.reverse(numeros);

    //y listo solo imprimimos en pantalla

    system.out.println("Numeros de mayor a menor"+numeros.toString);

  2. Buenas, quizá vengo tarde pero hay un pequeño error en el código donde haces los comparator. Tendría que ser así

    Collections.sort(personas, new Comparator<Personas>(){

    //El metodo compare

    });

    Ya que si el Comparator se pone como está publicado, los parametros del metodo compare seran del tipo Object y no del tipo Persona

  3. hola soy nuevo en esto de programar me gustaria saber como aria esta pregunta en la codificacion ¿Se requiere que los valores de las edades y los nombres de las personas sean introducidos por el usuario? gracias 

    1. Pues depende de lo que se necesite. Puedes optar por consola o por interfaz de usuario, luego para guardar los datos hay un sin fin de maneras de tratarlos: Arrays, Objetos, List, Maps.

  4. si la explicacion esta muy bien, pero sin utilizar ArrayList y mucho menos String y lo realizo con  objetos, como lo puedo ordenar los datos insertado….??????????????

    1. Para poder ordenar algo tiene que estar en alguna estructura como array o List, sino son objetos sin relacción ninguna. Para relacionar objetos del List como indicamos más arriba puedes utilizar compare()

  5. Ramón buenos dias,

    Tengo una duda respecto a terminos en Java, cuando dices "Sobreescribir el Metodo" te refieres a ir hasta la clase Compare.java y meterle esas lineas de codigo (basado en los objetos que estoy usando)…

    De antemano muchas gracias!… 

    No ha sido la primera vez que me has salvado, pero en esta me he quedado atorado. (:

    1. No, en este caso no me refiero a sobrescribir métodos. Me he expresado mal, quería decir sustituir un valor por otro con put: nombreMap.put(K clave, V valor);

  6. hola tengo un array list cuyo codigo es el siguiente 

     

    public class New  {
    public static int frec;

     

    public static void main(String[] args) throws IOException {
          
         ArrayList<Person> peoplelist=new ArrayList<Person>();
        
         javax.swing.JFileChooser j= new javax.swing.JFileChooser();
                       j.showOpenDialog(j);
                        File f;
                
                  
                       
                        String path= j.getSelectedFile().getAbsolutePath();
                        String lectura="";
                         f = new File(path);
                         FileReader fr = new FileReader(f);
                        BufferedReader br = new BufferedReader(fr);
                        String line=null;
                       String aux;
         
         
         while((line=br.readLine())!=null){
         
         
         String [] peopleInfo=line.split(",");
         String fecha=peopleInfo[0];
         String serie=peopleInfo[1];
         String lote=peopleInfo[2].trim();
         String frecuencia=peopleInfo[3].trim();
         String diferencia=peopleInfo[4].trim();
         String Q=peopleInfo[5].trim() ;
          String nom_operador=peopleInfo[6];
         String num_operador=peopleInfo[7];
         
      frec=Integer.parseInt(frecuencia);
     
         double q=Double.parseDouble(Q);
         peoplelist.add(new Person(fecha,serie,lote,frecuencia,diferencia,Q,nom_operador,num_operador));
         
      
        
          
          
          
          
       }
         
      
         }
        
        
         
         
        }
        

    se trata de obtener el numero mayor en el campo frecuencia e imprimirlo como podria hacerlo? de antemano gracias

  7. Que chilera la forma en como lo explican, me ha ayudado a comprender mucho, pero tengo otra duda con esto especificamente: 

    tengo una clase donde se guardan todas mi ArrayList ejemplo:
    ArrayList<Persona>c_persona=new ArrayList<Persona>();

    y tengo mi clase persona: 
    String nombre:
    String Apellido:
    int Edad. 

    tengo mi Jframe e otra clase distinta donde introduzco los datos que necesito, toda la parte de ingreso de datos ya lo tengo pero cecesito hacer un ordenamiento con su atributo por edad y mostrarlo, e leído como lo tienen pero no logro comprender: pordrían ayudarme. Gracias desde ya

     

  8. Hola, tengo un ArrayList de características fisiologicas como presión arterial y glucosa en sangre, se supone que cada una de estas mediciones van asociadas a una fecha. Quería saber como devolver una lista en las que estas características estén ordenadas por fecha. Gracias:)

    1. Hola,
      Si tienes un ArrayList con objetos con las características fisiológicas, junto otros datos como fechas, etc. Lo único que tienes que hacer es un sort con un nuevo Comparator() que compare por la variable de fecha.

  9. Buenas tarde tengo que realizar una venta de un libro y me quede trabado en la impresión de la lista del libro me podrian dar una mano? desde ya muchas gracias!

    package Main;

    import Clientes.Cliente;
    import Gestores.GestorVentaDeLibro;
    import Comprar.VentaDeLibro;
    import Gestores.GestorClienteComun;
    import Gestores.GestorClienteVip;
    import Gestores.GestorLibrosDigitales;
    import Gestores.GestorLibrosImpresos;
    import Libros.LibrosDigitales;
    import Libros.LibrosImpresos;

    import java.util.ArrayList;
    import java.util.List;

    import javax.swing.text.html.HTMLDocument.Iterator;

    import Libros.Libro;

    public class VenderLibros {

    public static void main(String[] args) {

    // CREAR UN CLIENTE COMUN
    GestorClienteComun gcc = new GestorClienteComun();
    Cliente clienteComun = gcc.registrarClienteComun(“Jesus”, “Davila”, “Aconcagua”, 239, “CABA”, “CABA”,49877458, “DODO”, 32230461, “Jebuss”, 500);

    //CREAR UN CLIENTE VIP
    GestorClienteVip gcv = new GestorClienteVip();
    Cliente clienteVip = gcv.registrarClienteVip(“Hugo”, “Ferrand”, “Pringles”, 4239, “Lanus”, “BSAS”, 1145254781, “Kratos”, 26230461, “ZaZaZa”, 200);

    //CREAR 1 LIBRO DIGITAL
    GestorLibrosDigitales ld = new GestorLibrosDigitales();
    LibrosDigitales libroDigital = ld.registarLibroDigital(“Expreso de media noche”,”Billy Hayes”,120.50, “kjjkgkjg”,”Aconcagua”,2);

    //CREAR UN LIBRO IMPRESO
    GestorLibrosImpresos li = new GestorLibrosImpresos();
    LibrosImpresos libroImpreso = li.registarLibroImpreso(“Cianuro espumoso”,”Agatha Christie”,180.90, “juerr3″,”Molino”,165);

    // VEDER UN LIBRO A UN CLIENTE
    GestorVentaDeLibro cc = new GestorVentaDeLibro();
    List libros = new ArrayList();
    libros.add(libroDigital);
    libros.add(libroImpreso);

    //Esta es la parte que no entiendo como hacerlo!!!

    VentaDeLibro cld = cc.venderLibro(“15/Nov/2014”, 1, libros, clienteComun);
    System.out.println(“La fecha es: ” );
    System.out.println(“Libro” + libros.size()+libroImpreso);
    System.out.println(“Libro ” + libros.size());

    // VENDER OTRO LIBRO A OTRO CLIENTE

    }

    }

    1. Hola Hugo,

      Por lo que leo lo que haces tan solo es añadir los libros a un ArrayList, por lo que entiendo que actuaría como de “carro de la compra”. Si esto es así (es lo que he entendido), el GestorVentaDeLibro será quien se encargue de hacer el resto y le tendrías que pasar los parámetros en el método venderLibro() (esto es un foreach al ArrayList libros), y así por cada cliente. No sé si es lo que necesitas.

  10. una pregunta, tengo un arraylist de planes turisticos, en donde tengo en cada posicion muchos datos como destino, cupos, costo, fecha, lo que necesito es ordenar cada posicion del array solo con costo para que se me organicen los planes turisticos del que tiene un mayor costo a un menor costo para que un cliente pueda verlos, ahi como se realizaria.

    Gracias por adelantado 😀

    1. Hola Sebastián,

      lo tienes muy sencillo. Supongo que tendrás una estructura de datos del tipo:
      List miLista = ArrayList<PlanTuristico>();
      y en cada objeto de cada PlanTuristico tienes los datos que indicas.
      Tan solo tienes que hacer sort() con un nuevo Comparator(), al igual que en este ejemplo, donde compares cada precio. Y lo tienes hecho 🙂

  11. una pregunta como hago para ordenar una lista de forma alfabética me explico mi lista es de articulo
    mi clases es la siguiente
    class xxx{
    String autor;
    String titulo;
    String fecha;
    }
    y me pide que lo ordene alfabéticamente por el titulo

    1. Hola Jesús,

      desde el sort con el compare podrías ir preguntando cuál es mayor que el otro. Un ejemplo sería:
      Collections.sort(lista, new Comparator() {
      @Override
      public int compare(final xxx obj1, final xxx obj2) {
      return obj1.getTitulo().compareTo(obj2.getTitulo());
      }
      } );

      1. asi estaria bien??…

        Collections.sort(lpf, new Comparator() {

        @Override
        public int compare(PersonaForm o1, PersonaForm o2) {
        return o1.getPaterno().compareTo(o2.getPaterno());
        }
        });

        1. Hola Vitmar,
          Estaría correcto también.
          Te aclaro lo del final en el parámetro de la función; para que veas que no te influye. No sé si sabes el uso de “final” en variables globales, pero funciona igual en parámetros de función. El “final” convierte a una variable en NO modificable, por ejemplo para constantes (el valor del número pi no lo vamos a querer modificar). Al aplicarlo al parámetro de una función estamos diciendo que no vamos a modificar el dato que nos entre a la función. ¿Podríamos no ponerlo? Podríamos, pero al poner “final” a una variable el ordenador consume menos recursos (por tanto menos batería si nuestro programa se ejecuta en un móvil por ejemplo)

  12. Hola muchas gracias por el tutorial de verdad me ayudo mucho, si me pudieras ayudar con este punto te lo agradeceria aun mas.
    tengo un arraylist que esta cargado con informacion de libro, es decir cada posicion en el arraylist tiene los siguientes datos: (int CodigodelLibro, String Titulo, String Autor, String Editorial)
    y necesito que ingresando un autor el programa recorra el arraylist e imprima los libros que sean del mismo autor.
    muchas gracias por adelantado

  13. Buenas, estoy creando una clase para ordenar una lista de objetos según su atributo
    El objeto de la lista se llama cliente.
    Hago el método para ordenar por nombre y sobrescribo, pero me salen 3 errores:
    -Me sugiere que declare la clase abstracta
    -Me dice que el método sort no es aplicable para esos argumentos
    -Me dice el método compare debería sobrescribir o implementar un método “supertype”
    Adjunto el código y agradezco la ayuda.

    import java.util.Collections;
    import java.util.Comparator;

    public class Ordenar implements Comparable {
    public Cliente[] tempClientes;
    public Articulo[] tempArticulos;

    public Ordenar(Cliente[] clientes, Articulo[] articulos){
    tempClientes = clientes;
    tempArticulos = articulos;
    }

    public Cliente[] sortNombre(Cliente[] lista){
    tempClientes = lista;
    Collections.sort(tempClientes, new Comparator(){
    @Override
    public int compare(Cliente p1, Cliente p2){
    return new String(p1.getNombre()).compareTo(new String(p2.getNombre()));
    }
    });
    return tempClientes;
    }
    }

  14. Hola

    Muchas gracias por la explicación, me ha servido bastante.

    Tengo una duda. Estoy haciendo un proyecto en NetBeans e hice una clase en la cual sobre escribí el compare de la clase Comparator como lo mencionas.

    NetBeans me dice que mi clase no es abstracta y que no sobre escribo el método compare en Comparator.

    ¿Qué está sucediendo?

    1. Hola,

      fíjate que el “new Comparator(){…}” lo estés pasando como evento (como parámetro de la función sort() ). Y dentro del cuerpo de “Comparator(){aquí entre las llaves}” sea donde hagas la sobrescritura (@override) del método compare(). Si lo pones fuera te dirá lo de que tu clase no es abstracta 😉

  15. nesesito un ejemplo de optener valores numericos de un joptionpane solo uno… y este que almacene todos los valores numericos en un array ya k ya llevo hecho hasta los operandos solo me falta almacenar los valores numericos para k asi me haga la operacion como si fuera una calculadora

  16. Excelente solución, ahora, me queda una duda, ¿como puedo lograr eso mismo pero alfabéticamente?

    Tengo que ordenar por unidadEjecutora y por entidad varios elementos

    unidadejecutora|entidad
    128 Guanajuato
    128 Aguascalientes
    101 Aguascalientes
    101 DistritoFederal

    tendría que quedar así.

    unidadejecutora|entidad
    101 Aguascalientes
    101 DistritoFederal
    128 Aguascalientes
    128 Guanajuato

    apreciaría tu ayuda. gracias!

    1. Hola Ramón,

      se hace igual, con el método sort(), ya que ordena también listas de Strings. Para tu ejemplo:
      List miLista = new ArrayList();
      miLista.add(“128 Guanajuato”);
      miLista.add(“128 Aguascalientes”);
      miLista.add(“101 Aguascalientes”);
      miLista.add(“101 DistritoFederal”);
      Collections.sort(miLista);

      Devuelve el resultado ordenado de:
      101 Aguascalientes
      101 DistritoFederal
      128 Aguascalientes
      128 Guanajuato

    2. Te respondo otra vez, ya que creo que te refieres a que tienes los datos en objetos Pojo (y dejo el anterior comentario, por si te sirviera). Es decir, que tendrías una clase que voy a llamar “Entidad.java” en la que guardas un número entero y un nombre. Por lo que podemos rellenar la lista del siguiente modo:

      List miLista = new ArrayList();
      miLista.add(new Entidad(128, “Guanajuato”));
      miLista.add(new Entidad(128, “Aguascalientes”));
      miLista.add(new Entidad(101, “Aguascalientes”));
      miLista.add(new Entidad(101, “DistritoFederal”));

      Luego, para ordenar, solo has de seguir el tutorial y verás que puedes sobrescribir Comparator como sigue:

      Collections.sort(miLista, new Comparator() {
      @Override
      public int compare(Entidad ent1, Entidad ent2) {
      return new Integer(ent1.id).compareTo(ent2.id);
      }
      });

      La anterior devuelve lo que necesitas, ya que ordena por id. Si quisieras ordenar además por nombre, tendrías que jugar con los enteros devueltos por el método compareTo(). Aunque te recomendaría que implementaras la clase Comparable dentro de la clase Pojo y que comparases uno a uno como el id del ejemplo anterior (y lo mismo para el String del nombre):
      public static Comparator compararId = new Comparator() {
      public int compare(Entidad ent1, Entidad ent2) {
      return Integer(ent1.id).compareTo(ent2.id);
      }
      };

        1. Apliqué lo siguiente…
          Tengo mi lista..

          unidadejecutora|entidad
          128 Guanajuato
          128 Aguascalientes
          101 Aguascalientes
          101 DistritoFederal

          //implementé comparable como me dijiste en mi clase Pojo
          public class EstructuraReporte implements Comparable {
          private Integer unidad_ejecutora;
          private String entidad;

          public Integer getUnidad_ejecutora() {
          return unidad_ejecutora;
          }

          public void setUnidad_ejecutora(Integer unidad_ejecutora) {
          this.unidad_ejecutora = unidad_ejecutora;
          }

          public String getEntidad() {
          return entidad;
          }

          public void setEntidad(String entidad) {
          this.entidad = entidad;
          }

          //aplique el compareTo
          public int compareTo(EstructuraReporte o) {
          //concatenando el valor texto de unidad_ejecutora y la entidad
          String a=new String(String.valueOf(this.unidad_ejecutora)+this.entidad);
          String b=new String(String.valueOf(o.unidad_ejecutora)+o.entidad);
          //comparo y listo.
          return a.compareTo(b);
          }
          }

          y con un respectivo

          Collections.sort(lista);

          obtuve la lista con el orden que quería

          unidadejecutora|entidad
          101 Aguascalientes
          101 DistritoFederal
          128 Aguascalientes
          128 Guanajuato

          Agradezco la orientación…

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies

ACEPTAR
Aviso de cookies