Ir al contenido principal

Instalando Apache NetBeans 10 y configurarlo con Jakarta EE

Comparable y Comparator

Comparable y Comparator
Tenemos una lista de objetos como Persona, o Producto, pero necesitamos ordenarlo ¿Cómo lo hacemos?

Aquí veremos, en un pequeño tutorial, cómo ordenar colecciones en Java.

Olvídense del ordenamiento de búrbuja, quickSort... java lo tiene todo.

Una colección en Java puede tener sus elementos ordenados.
Consideremos el siguiente código:

       List<String> nombres=Arrays.asList("Carlos","Ana","Dionisio","Bernardo");
       System.out.println("lista original:"+nombres);

       Collections.sort(nombres);
       System.out.println("lista ordenada:"+nombres);

La función Collections.sort() nos ordena una lista cualquiera.

Ahora bien, consideremos el siguiente código, donde se agregan elementos a un conjunto (java.util.Set). El conjunto será uno ordenado de por sí, sin necesidad de llamar a un método en especial:

        Set<String> otrosNombres = new TreeSet<>();
        otrosNombres.add("Mario");
        otrosNombres.add("Fernando");
        otrosNombres.add("Omar");
        otrosNombres.add("Juana");

        System.out.println("conjunto ordenado:" + otrosNombres);


Funcionan correctamente, porque cada elemento de las colecciones son comparables entre sí. Para que un objeto sea comparable, su clase debe implementar la interfaz java.lang.Comparable.

Esto quiere decir, que si queremos que una lista de objetos - o un conjunto - tenga sus elementos ordenados, y esos objetos son de una clase que hemos hecho, es necesario que nuestra clase implemente la interfaz java.lang.Comparable

Consideremos, entonces, una clase Persona, que tiene algunas propiedades:
class Persona {

    private int idPersona;
    private String nombre;
    private java.util.Date fechaNacimiento;

    public Persona() {
    }

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

    public int getIdPersona() {
        return idPersona;
    }

    public void setIdPersona(int idPersona) {
        this.idPersona = idPersona;
    }

    public String getNombre() {
        return nombre;
    }

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

    public java.util.Date getFechaNacimiento() {
        return fechaNacimiento;
    }

    public void setFechaNacimiento(java.util.Date fechaNacimiento) {
        this.fechaNacimiento = fechaNacimiento;
    }

    @Override
    public String toString() {
        return String.format("persona{idPersona:%1s,nombre:%2s}", idPersona, nombre);
    }
}


Entonces, si queremos que los objetos que al guardarse en una colección (java.util.Set o java.util.List) estén ordenados por el campo nombre, debemos (primero) implementar la interfaz Comparable.

//...
class Persona implements Comparable<Persona> {
//...


Y Segundo, implementar su método de comparación, aquí es donde definimos qué campo vamos a utilizar para ordenar:
//...
    @Override
    public int compareTo(Persona o) {
        return this.nombre.compareTo(o.nombre);
    }
//...


Ahora, cuando usemos una colección para ordenar, el ordenamiento será automático:

        Set<Persona> personas = new TreeSet<>();
        personas.add(new Persona(1, "Mario"));
        personas.add(new Persona(2, "Fernando"));
        personas.add(new Persona(3, "Omar"));
        personas.add(new Persona(4, "Juana"));

        System.out.println("conjunto ordenado de personas: " + personas);



Ahora, siempre será ordenado por nombre. Pero, ¿si en otro momento deseamos que sea ordenado por fecha de nacimiento u otro campo sin afectar el campo de ordenamiento predeterminado?

Para ello debemos utilizar un comparador de elementos. Un comparador es una clase de apoyo que será utilizada para los métodos de ordenamiento. Esto se logra implementando la interfaz java.util.Comparator

Para continuar con nuestro ejemplo, creemos la siguiente clase que implemente la interfaz mencionada
class OrdenarPersonaPorId implements Comparator<Persona> {

    @Override
    public int compare(Persona o1, Persona o2) {
        return o1.getIdPersona() - o2.getIdPersona();
    }
}


El método compare() debe devolver lo siguiente:
CondiciónValor que debe devolver
o1 < o2un número menor a cero
o1 == o2cero
o1 > o2un mayor menor a cero

Ahora bien, para utilizar este comparador, debemos usar el parámetro adicional de Collections.sort().
        List<Persona> otrasPersonas = Arrays.asList(new Persona(4, "Juana"),
                new Persona(2, "Fernando"),
                new Persona(1, "Mario"),
                new Persona(3, "Omar"));
        Collections.sort(otrasPersonas, new OrdenarPersonaPorId());
        System.out.println("lista de personas ordenadas por ID:" + otrasPersonas);

... o el parámetro del constructor de java.util.TreeSet.
        Set<Persona> conjuntoPersonas = new TreeSet<>(new OrdenarPersonaPorId());
        conjuntoPersonas.add(new Persona(3, "Omar"));
        conjuntoPersonas.add(new Persona(4, "Juana"));
        conjuntoPersonas.add(new Persona(2, "Fernando"));
        conjuntoPersonas.add(new Persona(1, "Mario"));

        System.out.println("conjunto de personas ordenadas por ID:" + conjuntoPersonas);



El código completo para este ejemplo lo podemos ver aquí:

Facebook

Twitter

Comentarios

Entradas más populares de este blog

RESTful... la forma más ligera de hacer WebServices (Parte 1)

Quienes hayan usado SOAP para WebService, sabrán que es bien fácil de diseñar, pero algo complicado de consumir: se necesita toda una API para construir los clientes utilizando el WSDL. Por ejemplo, para PHP se necesita de la biblioteca NuSOAP. Entonces, para lograr el concepto de "lenguaje único XML" es un dolor de cabeza. Y más aún si el cliente es tan simple como JavaScript, manejar XML de SOAP provocaría suicidos masivos... o no usar WebServices.

Además, con SOAP se permite crear un solo servicio y ponerle varios métodos. Esto puede llevar a un mal diseño del servicio ya que podría tener un servicio que haga de todo: por ejemplo, un servicio de manejo de Clientes que permita también manejar Proveedores.

RESTful es una propuesta muy interesante de Roy Fielding que permite manejar los servicios web con métodos definidos, manteniendo la simpleza del protocolo como XML, pero que cada servicio sea identificado únicamente con un solo URI.

En este post veremos cómo crear un Ser…

¿Por valor o por referencia?

Esta es una pregunta existencial para todo programador Java. Cada uno encuentra una respuesta satisfactoria. Pero ahora veremos, basándonos en el libro para Certificación SCJP 1.5 de Katty Sierra, sobre la respuesta correcta.

Contraseñas encriptadas con Java

¿Quién no ha querido encriptar texto o archivo? Hay diversas maneras para hacer eso, por ejemplo, utilizando un diccionario donde se reemplazara cada caracter por un código.. y para poder desencriptarlo se debería utilizar el mismo diccionario para revertir el proceso. Pero si el diccionario cae en manos de alguien que no queremos que lo sepa, entonces estamos en peligro.
Cuando yo programaba en pascal, mi encriptación favorita era invirtiendo los bits... pero cualquiera también puede invertir los bits y listo.
Pero ya gente experta logró algoritmos de encriptación populares. Los más conocidos: MD5 y SHA.
En este post hablaremos cómo encriptar texto, sobretodo las contraseñas, utilizando MD5 o SHA.