Foros aprenderaprogramar.com

Aprender a programar => C, C++, C#, Java, Visual Basic, HTML, PHP, CSS, Javascript, Ajax, Joomla, MySql y más => Mensaje iniciado por: LuisM en 16 de Noviembre 2017, 21:47

Título: Interface Comparable y método compareTo (API Java). Comparar objetos (CU00913C)
Publicado por: LuisM en 16 de Noviembre 2017, 21:47
Hola a todos !! Dejo a continuación el código del ejercicio propuesto CU00913C del tutorial gratuito de programación Java avanzada ofrecido en aprenderaprogramar. Desde ya, muchas gracias por la atención. Un saludo,

Luis

EJERCICIO

Utilizando Comparable y compareTo resuelve el siguiente problema donde debemos partir de una clase Persona con atributos nombre, edad y altura. Queremos ordenar por edad y por altura a las siguientes personas:                   

Nombre           Altura          Edad
Mario                 187               22
Pepe                 173               52
Manuel              158               27
David                164               25
Alberto              184              80

Debemos comparar las personas y ordenarlas por altura primero (de mayor a menor) y por edad (de menor a mayor) después. Por pantalla debe mostrarse la lista de personas sin ordenar, ordenada por altura y ordenada por edad. Ejemplo de ejecución:
Citar
Personas sin ordenar

1. Mario - Altura: 187 - Edad: 22
2. Pepe - Altura: 173 - Edad: 52
3. Manuel - Altura: 158 - Edad: 27
4. David - Altura: 164 - Edad: 25
5. Alberto - Altura: 184 - Edad: 80

 

Personas ordenadas por altura

1. Mario - Altura: 187 - Edad: 22
2. Alberto - Altura: 184 - Edad: 80
3. Pepe - Altura: 173 - Edad: 52
4. David - Altura: 164 - Edad: 25
5. Manuel - Altura: 158 - Edad: 27

 

Personas ordenadas por edad

1. Mario - Altura: 187 - Edad: 22
2. David - Altura: 164 - Edad: 25
3. Manuel - Altura: 158 - Edad: 27
4. Pepe - Altura: 173 - Edad: 52
5. Alberto - Altura: 184 - Edad: 80


Solución propuesta:


Clase Persona

Código: [Seleccionar]
/* Ejemplo Clase e Interfaz Cloneable aprenderaprogramar.com */
public class Persona implements Comparable<Persona>, Cloneable{
   public String nombre;
   public int altura, edad;
      public Persona(String nombre, int altura, int edad) {
          this.nombre = nombre;
          this.altura = altura;
          this.edad = edad;
      }
      public Persona clone()   {
          Persona clon = new Persona(this.nombre, this.altura, this.edad);
          return clon;
        }
      public int compareTo(Persona o) {
          int resultado=0;
          int resultado1=0;
            if (this.edad<o.edad) { resultado1 = -1;}
                else
                    if (this.edad>o.edad) { resultado1 = 1;}
                         else {
                             resultado1 = 0;
            }
          int resultado2=0;
            if (this.altura<o.altura) { resultado2 = -1;}
                else
                    if (this.altura>o.altura) { resultado2 = 1;}
                         else {
                               resultado2 = 0;
            }
          resultado = resultado1+resultado2; 
          return resultado ;
      }
}


Clase Programa - (main)

Código: [Seleccionar]
/* Ejemplo Clase e Interface Comparable aprenderaprogramar.com */
public class Programa {
    public static void main(String arg[]) {
         Persona p1 = new Persona("Mario",187,22);
         Persona p2 = new Persona("Pepe",173,52);   
         Persona p3 = new Persona("Manuel",158,27);
         Persona p4 = new Persona("David",164,25);   
         Persona p5 = new Persona("Alberto",184,80);
         Persona pAux = new Persona("",0,0);
         Persona px = new Persona("",0,0);
         // orden cargado
         System.out.println("Personas sin ordenar");
         System.out.println("1. "+p1.nombre+" - Altura: "+p1.altura+" - Edad: "+p1.edad);
         System.out.println("2. "+p2.nombre+" - Altura: "+p2.altura+" - Edad: "+p2.edad);
         System.out.println("3. "+p3.nombre+" - Altura: "+p3.altura+" - Edad: "+p3.edad);
         System.out.println("4. "+p4.nombre+" - Altura: "+p4.altura+" - Edad: "+p4.edad);
         System.out.println("5. "+p5.nombre+" - Altura: "+p5.altura+" - Edad: "+p5.edad);         
         System.out.println("");
         
         Persona cp1 = p1.clone();
         Persona cp2 = p2.clone();
         Persona cp3 = p3.clone();
         Persona cp4 = p4.clone();
         Persona cp5 = p5.clone();
         
         cp1.edad=0;
         cp2.edad=0;
         cp3.edad=0;
         cp4.edad=0;
         cp5.edad=0;

         System.out.println("Personas ordenadas por altura");
         if (cp1.compareTo(cp2)<0){pAux=cp2; px=p2; cp2=cp1; p2=p1; cp1=pAux; p1=px;}
         if (cp1.compareTo(cp3)<0){pAux=cp3; px=p3; cp3=cp1; p3=p1; cp1=pAux; p1=px;}
         if (cp1.compareTo(cp4)<0){pAux=cp4; px=p4; cp4=cp1; p4=p1; cp1=pAux; p1=px;}
         if (cp1.compareTo(cp5)<0){pAux=cp5; px=p5; cp5=cp1; p5=p1; cp1=pAux; p1=px;}
         
         if (cp2.compareTo(cp3)<0){pAux=cp3; px=p3; cp3=cp2; p3=p2; cp2=pAux; p2=px;}
         if (cp2.compareTo(cp4)<0){pAux=cp4; px=p4; cp4=cp2; p4=p2; cp2=pAux; p2=px;}
         if (cp2.compareTo(cp5)<0){pAux=cp5; px=p5; cp5=cp2; p5=p2; cp2=pAux; p2=px;}

         if (cp3.compareTo(cp4)<0){pAux=cp4; px=p4; cp4=cp3; p4=p3; cp3=pAux; p3=px;}
         if (cp3.compareTo(cp5)<0){pAux=cp5; px=p5; cp5=cp3; p5=p3; cp3=pAux; p3=px;}

         if (cp4.compareTo(cp5)<0){pAux=cp5; px=p5; cp5=cp4; p5=p4; cp4=pAux; p4=px;}

         System.out.println("1. "+p1.nombre+" - Altura: "+p1.altura+" - Edad: "+p1.edad);
         System.out.println("2. "+p2.nombre+" - Altura: "+p2.altura+" - Edad: "+p2.edad);
         System.out.println("3. "+p3.nombre+" - Altura: "+p3.altura+" - Edad: "+p3.edad);
         System.out.println("4. "+p4.nombre+" - Altura: "+p4.altura+" - Edad: "+p4.edad);
         System.out.println("5. "+p5.nombre+" - Altura: "+p5.altura+" - Edad: "+p5.edad);
         System.out.println("");
         
         cp1 = p1.clone();
         cp2 = p2.clone();
         cp3 = p3.clone();
         cp4 = p4.clone();
         cp5 = p5.clone();
         cp1.altura=0;
         cp2.altura=0;
         cp3.altura=0;
         cp4.altura=0;
         cp5.altura=0;
         System.out.println("Personas ordenadas por edad");
         if (cp1.compareTo(cp2)>0){pAux=cp2; px=p2; cp2=cp1; p2=p1; cp1=pAux; p1=px;}
         if (cp1.compareTo(cp3)>0){pAux=cp3; px=p3; cp3=cp1; p3=p1; cp1=pAux; p1=px;}
         if (cp1.compareTo(cp4)>0){pAux=cp4; px=p4; cp4=cp1; p4=p1; cp1=pAux; p1=px;}
         if (cp1.compareTo(cp5)>0){pAux=cp5; px=p5; cp5=cp1; p5=p1; cp1=pAux; p1=px;}
         
         if (cp2.compareTo(cp3)>0){pAux=cp3; px=p3; cp3=cp2; p3=p2; cp2=pAux; p2=px;}
         if (cp2.compareTo(cp4)>0){pAux=cp4; px=p4; cp4=cp2; p4=p2; cp2=pAux; p2=px;}
         if (cp2.compareTo(cp5)>0){pAux=cp5; px=p5; cp5=cp2; p5=p2; cp2=pAux; p2=px;}

         if (cp3.compareTo(cp4)>0){pAux=cp4; px=p4; cp4=cp3; p4=p3; cp3=pAux; p3=px;}
         if (cp3.compareTo(cp5)>0){pAux=cp5; px=p5; cp5=cp3; p5=p3; cp3=pAux; p3=px;}

         if (cp4.compareTo(cp5)>0){pAux=cp5; px=p5; cp5=cp4; p5=p4; cp4=pAux; p4=px;}

         System.out.println("1. "+p1.nombre+" - Altura: "+p1.altura+" - Edad: "+p1.edad);
         System.out.println("2. "+p2.nombre+" - Altura: "+p2.altura+" - Edad: "+p2.edad);
         System.out.println("3. "+p3.nombre+" - Altura: "+p3.altura+" - Edad: "+p3.edad);
         System.out.println("4. "+p4.nombre+" - Altura: "+p4.altura+" - Edad: "+p4.edad);
         System.out.println("5. "+p5.nombre+" - Altura: "+p5.altura+" - Edad: "+p5.edad);
         System.out.println("");

    }
}
Título: Re:Interface Comparable y método compareTo (API Java). Comparar objetos (CU00913C)
Publicado por: fmartinez25 en 27 de Noviembre 2017, 22:40
Hola.

En mi solución solo he usado la interface Comparable, no la Cloneable, ya que no se trata de guardar la lista de personas ordenadas, sino de mostrarlas ordenadas, por lo que me limito a crear un array adicional de 5 personas cuyos elementos apuntan ordenadamente, según el criterio de ordenación especificado, a las instancias de Persona que se crean al principio del método main. Así se usaría menos memoria.

No he encontrado la manera de sobreescribir el método compareTo de forma que pueda usarse para cualquiera de los dos criterios de ordenación, por lo que he tenido que crear otro método para la altura (he considerado que es más habitual ordenar por edades).

Ahí adjunto mi solución. Espero las críticas del resto de usuarios.

Clase Persona
Código: [Seleccionar]
public class Persona implements Comparable<Persona>{
    private String nombre;
    private int edad, altura;
   
    public Persona(String nombre, int edad, int altura){
        this.nombre=nombre;
        this.edad=edad;
        this.altura=altura;
    }
   
    public String getNombre(){return this.nombre;}
    public int getEdad(){return this.edad;}
    public int getAltura(){return this.altura;}
   
    @Override
    public int compareTo(Persona o){
        int resultado=0;
        if (this.edad>o.edad){ resultado=1; }
        else if (this.edad<o.edad){ resultado=-1; }
        return resultado;
        }
   
    public int compareToAltura(Persona o){
        int resultado=0;
        if(this.altura>o.altura){resultado=+1;}
        else if (this.altura<o.altura){resultado=-1;}
        return resultado;
    }
    @Override
    public String toString(){
        return this.nombre+" - Altura: "+this.altura+" - Edad: "+this.edad;
    }
}

Clase con el método main
Código: [Seleccionar]
public class CU00913C {

    public static void main(String[] args) {
        Persona[] personas = new Persona[5];
        personas[0] = new Persona("Mario", 22, 187);
        personas[1] = new Persona("Pepe", 52, 173);
        personas[2] = new Persona("Manuel", 27, 158);
        personas[3] = new Persona("David", 25, 164);
        personas[4] = new Persona("Alberto", 80, 184);
        Persona[] personasOrdenadas = new Persona[5];
       
        System.out.println("Personas sin ordenar");
        for(Persona tmp:personas){System.out.print(tmp.toString()+"\n");}
        System.out.println();
       
        System.out.println("Personas ordenadas por altura");
        personasOrdenadas=OrdenarAltura(personas);
        for(Persona tmp:personasOrdenadas){System.out.print(tmp.toString()+"\n");}
        System.out.println();
       
        System.out.println("Personas ordenadas por edad");
        personasOrdenadas=OrdenarEdad(personas);
        for(Persona tmp:personasOrdenadas){System.out.print(tmp.toString()+"\n");}
        System.out.println();
       
}
    //Ordena crecientemente por edades sin clonar ls objetos persona
    public static Persona[] OrdenarEdad(Persona[] personas){
        Persona[] ordenado = new Persona[5];
        ordenado[0]=personas[0];
        for (int i=1;i<5;i++){
            int j=i;
            while (j>0&&personas[i].compareTo(ordenado[j-1])<0){
                ordenado[j]=ordenado[j-1];
                j--;
            }
            ordenado[j]=personas[i];
        }
        return ordenado;
    }
   
    //Ordena decrecientemente por alturas sin clonar los objetos persona
    public static Persona[] OrdenarAltura(Persona[] personas){
        Persona[] ordenado = new Persona[5];
        ordenado[0]=personas[0];
        for (int i=1;i<5;i++){
            int j=i;
            while (j>0&&personas[i].compareToAltura(ordenado[j-1])>0){
                ordenado[j]=ordenado[j-1];
                j--;
            }
            ordenado[j]=personas[i];
        }
        return ordenado;
    }
Título: Re:Interface Comparable y método compareTo (API Java). Comparar objetos (CU00913C)
Publicado por: LuisM en 28 de Noviembre 2017, 22:57
Hola fmartinez25 !! Muy buena solución. Me gustó como lo hiciste.  :)
En mi ejercicio unifiqué en un solo método la comparación de personas. Es por eso que uso la clonación para anular el atributo por el que no quiero ordenar.

Un saludo,
Luis