Autor Tema: Reducir la complejidad del código Java evitar anidamientos innecesarios CU00666B  (Leído 5679 veces)

Dimitar Stefanov

  • Experto
  • *****
  • Mensajes: 598
    • Ver Perfil
Una posible solución del ejercicio CU00666B del curso Java desde cero.

Citar
EJERCICIO

Crea una clase denominada ListaCantantesFamosos que al ser inicializada contenga un ArrayList con tres Strings que sean el nombre de cantantes famosos. Crea una clase test con el método main que inicialice un objeto ListaCantantesFamosos y usando un for extendido muestre los cantantes en la lista por pantalla. Se debe pedir al usuario un nombre más de cantante famoso, y una vez introducido mostrar la lista actualizada usando un for extendido. Una vez mostrada la lista actualizada, se debe dar opción a elegir entre volver a introducir otro cantante o salir del programa (se podrán introducir tantos cantantes como se desee, para ello usa un bucle while que dé opción a elegir al usuario).

Código "ListaCanstantesFamosos":

Código: [Seleccionar]
import java.util.ArrayList;

public class ListaCantantesFamosos{
    private ArrayList<String> listacantantesfamosos;
   
    public ListaCantantesFamosos(){
        listacantantesfamosos = new ArrayList<String>();
        listacantantesfamosos.add("Joan Bon Jovi");
        listacantantesfamosos.add("Michael Jackson");
        listacantantesfamosos.add("Julio Iglesias");
    }
   
    public void addNombre(String valor_nombre){
        listacantantesfamosos.add(valor_nombre);
    }
   
    public void cantantesEnLaLista(){
        int i = 1;
        for(String cantante: listacantantesfamosos){
            System.out.println("Cantante "+i+": "+cantante);
            i++;
        }
    }
}

Código "Test":

Código: [Seleccionar]
import java.util.Scanner;

public class Test{
    public static void main(String []args){
        System.out.println("Los cantantes famosos en la lista son:");
        ListaCantantesFamosos listacantantes = new ListaCantantesFamosos();
        listacantantes.cantantesEnLaLista();
        System.out.print("Introduzca otro cantante:");
        String entradaTeclado = "";
        Scanner entradaScaner = new Scanner(System.in);
        entradaTeclado = entradaScaner.nextLine();
        listacantantes.addNombre(entradaTeclado);
        listacantantes.cantantesEnLaLista();
        String entradaDesicion = "";
        System.out.print("Deseas entrar más cantante: Sí/No: ");
        entradaDesicion = entradaScaner.nextLine();
        while(true){
            if(entradaDesicion.equals("Sí") || entradaDesicion.equals("Si") || entradaDesicion.equals("sí")|| entradaDesicion.equals("si"))
            System.out.print("Introduzca otro cantante:");
            entradaTeclado = entradaScaner.nextLine();
            listacantantes.addNombre(entradaTeclado);
            listacantantes.cantantesEnLaLista();
            System.out.print("Deseas entrar más cantante: Sí/No: ");
            entradaDesicion = entradaScaner.nextLine();
            if(entradaDesicion.equals("No") || entradaDesicion.equals("no")){
            System.out.println("Gracias por utilizar nuestro programa.");
            break;
            }
        }
        }
}

Gracias
« Última modificación: 09 de Marzo 2016, 10:09 por César Krall »

Dimitar Stefanov

  • Experto
  • *****
  • Mensajes: 598
    • Ver Perfil
Re:CU00666B El for extendido o bucle for each en Java
« Respuesta #1 en: 04 de Marzo 2016, 16:52 »
Corrijo el código "Test":

Código: [Seleccionar]
import java.util.Scanner;

public class Test{
    public static void main(String []args){
        System.out.println("Los cantantes famosos en la lista son:");
        ListaCantantesFamosos listacantantes = new ListaCantantesFamosos();
        listacantantes.cantantesEnLaLista();
        System.out.print("Introduzca otro cantante:");
        String entradaTeclado = "";
        Scanner entradaScaner = new Scanner(System.in);
        entradaTeclado = entradaScaner.nextLine();
        if(entradaTeclado.equals("")==false){
        listacantantes.addNombre(entradaTeclado);
        listacantantes.cantantesEnLaLista();}
        String entradaDesicion = "";
        System.out.print("Deseas entrar más cantante: Sí/No: ");
        entradaDesicion = entradaScaner.nextLine();
        while(entradaDesicion.equals("")){
                System.out.print("Deseas entrar más cantante: Sí/No: ");
                entradaDesicion = entradaScaner.nextLine();
        }
        while(true){
            if(entradaDesicion.equals("Sí") || entradaDesicion.equals("Si") || entradaDesicion.equals("sí")|| entradaDesicion.equals("si"))
            System.out.print("Introduzca otro cantante:");
            entradaTeclado = entradaScaner.nextLine();
            if(entradaTeclado.equals("")==false){
            listacantantes.addNombre(entradaTeclado);
            listacantantes.cantantesEnLaLista();}
            System.out.print("Deseas entrar más cantante: Sí/No: ");
            entradaDesicion = entradaScaner.nextLine();
            while(entradaDesicion.equals("")){
                System.out.print("Deseas entrar más cantante: Sí/No:");
                entradaDesicion = entradaScaner.nextLine();
            }
            if(entradaDesicion.equals("No") || entradaDesicion.equals("no")){
            System.out.println("Gracias por utilizar nuestro programa.");
            break;
            }
        }
        }
}

Así creo que cubre más posibilidades que se pueden dar por parte del usuario. En el caso de que no entre nada en el campo de cantante nuevo, mediante la condicional :

Código: [Seleccionar]
if(entradaTeclado.equals("")==false){
        listacantantes.addNombre(entradaTeclado);
        listacantantes.cantantesEnLaLista();}

no se añadirá nada.

También, en el caso de que no responda nada en la pregunta "Si desea o no añadir un cantante nuevo", dicha pregunta se preguntará hasta que no conteste algo gracias al bucle "while":

Código: [Seleccionar]
while(entradaDesicion.equals("")){
                System.out.print("Deseas entrar más cantante: Sí/No: ");
                entradaDesicion = entradaScaner.nextLine();
        }

Y únicamente se podra salir del bucle "while(true)" cuando el usuario conteste con: "No" o "no" mediante esta condicional:

Código: [Seleccionar]
if(entradaDesicion.equals("No") || entradaDesicion.equals("no")){
            System.out.println("Gracias por utilizar nuestro programa.");
            break;
            }

Gracias

César Krall

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2078
  • No vales por lo que dices, sino por lo que haces
    • Ver Perfil
    • aprenderaprogramar.com
Hola!

Ejercicio que deberías realizar de nuevo

- No se recomienda usar un bucle while true, hay una explicación en https://www.aprenderaprogramar.com/foros/index.php?topic=2570.0

- No se recomienda salir de un bucle while mediante break, comentado en https://www.aprenderaprogramar.com/foros/index.php?topic=4096.0

Saludos!
Responsable de departamento de producción aprenderaprogramar.com

Dimitar Stefanov

  • Experto
  • *****
  • Mensajes: 598
    • Ver Perfil
Buenas, César.

He conseguido hacer algo, pero no esta del todo bien el código.

Me ha quedado así:

Código: [Seleccionar]
import java.util.Scanner;

public class Test{
    public static void main(String []args){
        System.out.println("Los cantantes famosos en la lista son:");
        ListaCantantesFamosos listacantantes = new ListaCantantesFamosos();
        listacantantes.cantantesEnLaLista();
        System.out.print("Introduzca otro cantante:");
        String entradaTeclado = "";
        Scanner entradaScaner = new Scanner(System.in);
        entradaTeclado = entradaScaner.nextLine();
        if(entradaTeclado.equals("")==false){
        listacantantes.addNombre(entradaTeclado);
        listacantantes.cantantesEnLaLista();}
        String entradaDesicion = "";
        System.out.print("Deseas entrar más cantante: Sí/No: ");
        entradaDesicion = entradaScaner.nextLine();
        if(entradaDesicion.equals("No")==false || entradaDesicion.equals("no")==false || entradaDesicion.equals("Sí")==false || entradaDesicion.equals("sí")==false || entradaDesicion.equals("Si")==false || entradaDesicion.equals("si")==false){
        while(entradaDesicion.equals("Sí")==false){ //|| entradaDesicion.equals("No") == false || entradaDesicion.equals("no") == false){
                System.out.print("Deseas entrar más cantante: Sí/No: ");
                entradaDesicion = entradaScaner.nextLine();
        }
    }
        if(entradaDesicion.equals("No") || entradaDesicion.equals("no") ){
            System.out.println("Gracias por utilizar nuestro programa.");
            }
        while(entradaDesicion.equals("Sí") || entradaDesicion.equals("sí") || entradaDesicion.equals("Si") || entradaDesicion.equals("si") ){
            if(entradaDesicion.equals("Sí") || entradaDesicion.equals("Si") || entradaDesicion.equals("sí")|| entradaDesicion.equals("si"))
            System.out.print("Introduzca otro cantante:");
            entradaTeclado = entradaScaner.nextLine();
            if(entradaTeclado.equals("")==false){
            listacantantes.addNombre(entradaTeclado);
            listacantantes.cantantesEnLaLista();}
            System.out.print("Deseas entrar más cantante: Sí/No: ");
            entradaDesicion = entradaScaner.nextLine();
            while(entradaDesicion.equals("")){
                System.out.print("Deseas entrar más cantante: Sí/No:");
                entradaDesicion = entradaScaner.nextLine();
            }
            if(entradaDesicion.equals("No") || entradaDesicion.equals("no") ){
            System.out.println("Gracias por utilizar nuestro programa.");
            }
        }
        }
}

Ya verás, que cumpliéndose la primera condiciones, si

Código: [Seleccionar]
        if(entradaDesicion.equals("No")==false || entradaDesicion.equals("no")==false || entradaDesicion.equals("Sí")==false || entradaDesicion.equals("sí")==false || entradaDesicion.equals("Si")==false || entradaDesicion.equals("si")==false)
Entramos en un bucle infinito. Sólo se puede salir de él respondiendo a la pregutna  con un  "Sí".

No entiendo por qué no me deja poner más de una condición en el bucle while. Es decir, que quede así:

Código: [Seleccionar]
while(entradaDesicion.equals("No")==false || entradaDesicion.equals("no")==false || entradaDesicion.equals("Sí")==false || entradaDesicion.equals("sí")==false || entradaDesicion.equals("Si")==false || entradaDesicion.equals("si")==false){
//Instrucciones para cumplir
}

Gracias

Dimitar Stefanov

  • Experto
  • *****
  • Mensajes: 598
    • Ver Perfil
Buenas tardes, César.

Creo que he dado con la solución.

Así queda el código:

Código: [Seleccionar]
import java.util.Scanner;

public class Test01{
    public static void main(String []Args){
        System.out.println("Los cantantes famosos en la lista son:");
        ListaCantantesFamosos listacantantes = new ListaCantantesFamosos();
        listacantantes.cantantesEnLaLista();
        System.out.print("Introduzca otro cantante:");
        String entradaTeclado = "";
        Scanner entradaScaner = new Scanner(System.in);
        entradaTeclado = entradaScaner.nextLine();
        if(entradaTeclado.equals("")==false){
        listacantantes.addNombre(entradaTeclado);
        listacantantes.cantantesEnLaLista();}
        String entradaDesicion = "";
        System.out.print("Deseas entrar más cantante: Sí/No: ");
        entradaDesicion = entradaScaner.nextLine();
       
        //Contemplar todas las respuestas distintos a: "No","no","Sí","Si","sí" y "si". Todo lo que no sea opción que tengo como respuesta lo convierto en "noCorrecto"
        if(entradaDesicion.equals("No")==false && entradaDesicion.equals("no")==false && entradaDesicion.equals("Sí")==false && entradaDesicion.equals("Si")==false && entradaDesicion.equals("sí")==false && entradaDesicion.equals("si")==false){
                entradaDesicion = "noCorrecto";
                while(entradaDesicion.equals("noCorrecto")){
                System.out.print("Deseas entrar más cantante: Sí/No: ");
                entradaDesicion = entradaScaner.nextLine();
               
                 if(entradaDesicion.equals("Sí") || entradaDesicion.equals("Si") || entradaDesicion.equals("sí") || entradaDesicion.equals("si")){
                    entradaDesicion = "Sí";
                 }else if(entradaDesicion.equals("No")|| entradaDesicion.equals("no")){
                    entradaDesicion = "No";
                 }else if(entradaDesicion.equals("Sí")==false && entradaDesicion.equals("sí")==false && entradaDesicion.equals("Si")==false && entradaDesicion.equals("si")==false && entradaDesicion.equals("No")==false && entradaDesicion.equals("no")==false){
                    entradaDesicion = "noCorrecto";
                 }
             }
           }
       
       
       
       
       
       //En el caso de que la respuesta sea: "Sí", "Si", "sí" o "si"
        if(entradaDesicion.equals("Sí") || entradaDesicion.equals("Si") || entradaDesicion.equals("sí")|| entradaDesicion.equals("si")){
            entradaDesicion="Sí";
            while(entradaDesicion.equals("Sí")){
            System.out.print("Introduzca otro cantante:");
            entradaTeclado = entradaScaner.nextLine();
            if(entradaTeclado.equals("")==false){
            listacantantes.addNombre(entradaTeclado);
            listacantantes.cantantesEnLaLista();}
            System.out.print("Deseas entrar más cantante: Sí/No: ");
            entradaDesicion = entradaScaner.nextLine();
           
            //Valorar las respuestas otra vez
                 if(entradaDesicion.equals("Sí") || entradaDesicion.equals("Si") || entradaDesicion.equals("sí") || entradaDesicion.equals("si")){
                    entradaDesicion = "Sí";
                 }else if(entradaDesicion.equals("No")|| entradaDesicion.equals("no")){
                    entradaDesicion = "No";
                 }else if(entradaDesicion.equals("Sí")==false && entradaDesicion.equals("sí")==false && entradaDesicion.equals("Si")==false && entradaDesicion.equals("si")==false && entradaDesicion.equals("No")==false && entradaDesicion.equals("no")==false){
                    entradaDesicion = "noCorrecto";
                     while(entradaDesicion.equals("noCorrecto")){
                       System.out.print("Deseas entrar más cantante: Sí/No: ");
                       entradaDesicion = entradaScaner.nextLine();
               
                        if(entradaDesicion.equals("Sí") || entradaDesicion.equals("Si") || entradaDesicion.equals("sí") || entradaDesicion.equals("si")){
                        entradaDesicion = "Sí";
                        }else if(entradaDesicion.equals("Sí")==false && entradaDesicion.equals("sí")==false && entradaDesicion.equals("Si")==false && entradaDesicion.equals("si")==false && entradaDesicion.equals("No")==false && entradaDesicion.equals("no")==false){
                        entradaDesicion = "noCorrecto";
                        }
             }
           }
        }
       
    }
       
           
           
           
           
           
           //En el caso de que la respuesta sea un: "No" o "no"
            if(entradaDesicion.equals("No")==true || entradaDesicion.equals("no")){
            System.out.println("Gracias por utilizar nuestro programa.");
        }
           
           
    }
   
}



Entendí donde me equivocaba. Cuando ponía el código:

Código: [Seleccionar]
if(entradaDesicion.equals("No")==false || entradaDesicion.equals("no")==false || entradaDesicion.equals("Sí")==false || entradaDesicion.equals("Si")==false || entradaDesicion.equals("sí")==false || entradaDesicion.equals("si")==false){
 //Instrucciones...
}
if(entradaDesicion.equals("Sí") || entradaDesicion.equals("Si") || entradaDesicion.equals("sí") || entradaDesicion.equals("si")){
//Instrucciones...
}
if(entradaDesicion.equals("No")==true || entradaDesicion.equals("no")){
//Instrucciones...
}

me sorprendía de que entraba lo que entraba, siempre me entraba en la primera condición. Mirándolo mucho entendí que aunque entraría "sí" sí que cumplía con la condicional : "entradaDesicion.equals("si")==false", pero todas las además declaraciones en la misma condicional las cumplía. Y todo era porque utilizaba el operador "||" y no "&&". Una vez dado cuenta de ello, cambié el código a:

Código: [Seleccionar]
if(entradaDesicion.equals("No")==false && entradaDesicion.equals("no")==false && entradaDesicion.equals("Sí")==false && entradaDesicion.equals("Si")==false && entradaDesicion.equals("sí")==false && entradaDesicion.equals("si")==false){
 //Instrucciones...
}
if(entradaDesicion.equals("Sí") || entradaDesicion.equals("Si") || entradaDesicion.equals("sí") || entradaDesicion.equals("si")){
//Instrucciones...
}
if(entradaDesicion.equals("No")==true || entradaDesicion.equals("no")){
//Instrucciones...
}

y ahora sí que salta en las otras condiciones.

Gracias. (ahora creo que lo he hecho bien) :)

César Krall

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2078
  • No vales por lo que dices, sino por lo que haces
    • Ver Perfil
    • aprenderaprogramar.com
Hola!

En estos ejercicios no debes preocuparte por detalles como contemplar todas las posibles respuestas No-no-Si-si etc. lo importante es que te centres en los conceptos que se explican en cada entrega.

Nota: para ese tipo de comprobaciones existe en Java el método EqualsIgnoreCase que evita tener que escribir todas esas posibles combinaciones. Puedes leer explicación en https://www.aprenderaprogramar.com/foros/index.php?topic=1566.0

El código que has planteado hace cosas como introducir un condicional while dentro de un condicional if que luego tiene otro condicional while adicional otra vez dentro, esto no es un buen diseño. El while ya lleva condiciones, en general no resultará adecuado envolverlo en otra condición cuando el propio while ya permite incluir condiciones. Meter un while dentro de otro while sólo debe hacerse cuando sea estrictamente necesario y en este caso no lo es.

Estudia con atención el código propuesto en https://www.aprenderaprogramar.com/foros/index.php?topic=2262.0

Ahí ves un ejemplo de diseño sencillo. Tienes que intentar crear diseños de código con la menor complejidad posible. Tu solución no es buena porque tiene una gran complejidad sin ser realmente  necesaria.

Saludos!
Responsable de departamento de producción aprenderaprogramar.com

Dimitar Stefanov

  • Experto
  • *****
  • Mensajes: 598
    • Ver Perfil
Buenas tardes, César.

Tienes razón, es un código muy largo y complejo para un cometido sencillo. Yo también pensé lo mismo después de acabar el ejercicio.

A estas alturas debería centrarme en la esencia de cada entrega del curso y no intentar encontrar soluciones a cosas que aún no hemos estudiado. Supongo que cada cosa a su tiempo.

Gracias de nuevo, y sigo adelante:)

Saludos.

PD: Estoy estudiando los enlaces que me has adjuntado.

 

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".