Autor Tema: Interface Comparable y método compareTo (API Java). Comparar objetos (CU00913C)  (Leído 4881 veces)

LuisM

  • Intermedio
  • ***
  • APR2.COM
  • Mensajes: 131
    • Ver Perfil
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("");

    }
}
« Última modificación: 05 de Junio 2018, 19:19 por Ogramar »

fmartinez25

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 7
    • Ver Perfil
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;
    }

LuisM

  • Intermedio
  • ***
  • APR2.COM
  • Mensajes: 131
    • Ver Perfil
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

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".