Autor Tema: CU00667B ¿Cómo obtener varios atributos de un sólo objeto con Iterator?  (Leído 6105 veces)

palote el de los pericos

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 4
    • Ver Perfil
El código me funciona, aunque no sé si es el más adecuado, además, he tenido que usar un bucle for-each para obtener los atributos de los objetos porque no sabía cómo hacerlo con Iterator.
Código: [Seleccionar]
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Iterator;

public class ListaCantantesFamosos{
private ArrayList <CantanteFamoso> listaCantantes;
Scanner scan;
Iterator <CantanteFamoso> iterador;

class CantanteFamoso{
String nombre;
String discoSuperventas;
}

CantanteFamoso nuevoCantante;

ListaCantantesFamosos(){
listaCantantes = new ArrayList<>();
scan = new Scanner(System.in);
}

public void añadirCantantes(String nombre, String discoSuperventas){
nuevoCantante = new CantanteFamoso();
nuevoCantante.nombre = nombre;
nuevoCantante.discoSuperventas = discoSuperventas;
listaCantantes.add(nuevoCantante);
}

public void mostrarLista2(){
for(CantanteFamoso nombres : listaCantantes){
System.out.print(nombres.nombre+ " - ");
System.out.println(nombres.discoSuperventas);
}
}

public void mostrarLista(){
iterador = listaCantantes.iterator();
while(iterador.hasNext()){
System.out.println(iterador.next());
}
}

public void añadirCantantes(){
String aux1 = "";
do{
String aux2 = "";
System.out.println("¿Desea añadir otro nombre? (s/n)");
aux2 = scan.nextLine();
aux1 = aux2;
if(aux2.equalsIgnoreCase("s")){
nuevoCantante = new CantanteFamoso();
System.out.println("Introduzca el nombre del cantante: ");
nuevoCantante.nombre = scan.nextLine();
System.out.println("Introduzca el nombre de su disco más vendido: ");
nuevoCantante.discoSuperventas = scan.nextLine();
listaCantantes.add(nuevoCantante);
}
}while("s".equalsIgnoreCase(aux1));
for(CantanteFamoso nombres : listaCantantes){
System.out.print(nombres.nombre+ " - ");
System.out.println(nombres.discoSuperventas);
}
}

Código: [Seleccionar]
public class TestListaCantantesFamosos{
public static void main(String[]args){
ListaCantantesFamosos objmain = new ListaCantantesFamosos();
objmain.añadirCantantes("Sabina", "No me acuerdo");
objmain.añadirCantantes("Sabrina", "El que sea");
objmain.mostrarLista2();
objmain.añadirCantantes();
}
}

palote el de los pericos

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 4
    • Ver Perfil
Me respondo a mí mismo con la solución. He añadido dos maneras de hacerlo. Agradecería que algún experto me dijera que tal le parece el código (buenas prácticas, eficiencia, etc..)

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

public class ListaCantantesFamosos{
private ArrayList <CantanteFamoso> listaCantantes;
Scanner scan;
Iterator <CantanteFamoso> iterador;

class CantanteFamoso{
String nombre;
String discoSuperventas;


public String getNombre(){
return nombre;
}

public String getDiscoSuperventas(){
return discoSuperventas;
}

}

CantanteFamoso nuevoCantante;

ListaCantantesFamosos(){
listaCantantes = new ArrayList<>();
scan = new Scanner(System.in);
}

public void añadirCantantes(String nombre, String discoSuperventas){
nuevoCantante = new CantanteFamoso();
nuevoCantante.nombre = nombre;
nuevoCantante.discoSuperventas = discoSuperventas;
listaCantantes.add(nuevoCantante);
}

public void mostrarLista1(){
for(CantanteFamoso nombres : listaCantantes){
System.out.print(nombres.nombre+ " - ");
System.out.println(nombres.discoSuperventas);
}
}

public void mostrarLista2(){
iterador = listaCantantes.iterator();
while(iterador.hasNext()){
CantanteFamoso cantante = iterador.next();
System.out.println(cantante.nombre+" - "+cantante.discoSuperventas);
}
}

public void mostrarLista3(){
iterador = listaCantantes.iterator();
while(iterador.hasNext()){
CantanteFamoso cantante = iterador.next();
System.out.println(cantante.getNombre()+" - "+cantante.getDiscoSuperventas());
}
}

public void añadirCantantes(){
String aux1 = "";
do{
String aux2 = "";
System.out.println("¿Desea añadir otro nombre? (s/n)");
aux2 = scan.nextLine();
aux1 = aux2;
if(aux2.equalsIgnoreCase("s")){
nuevoCantante = new CantanteFamoso();
System.out.println("Introduzca el nombre del cantante: ");
nuevoCantante.nombre = scan.nextLine();
System.out.println("Introduzca el nombre de su disco más vendido: ");
nuevoCantante.discoSuperventas = scan.nextLine();
listaCantantes.add(nuevoCantante);
}
}while("s".equalsIgnoreCase(aux1));
for(CantanteFamoso nombres : listaCantantes){
System.out.print(nombres.nombre+ " - ");
System.out.println(nombres.discoSuperventas);
}
}

}

toni_apr

  • Avanzado
  • ****
  • Mensajes: 497
  • Curiosidad, es uno de los pilares del Conocimiento
    • Ver Perfil
Hola perico
En primer lugar me gusta el humor que pones en tu alias, seguro que  también se encontrará imaginación en tu código.

Has enviado un segundo mensaje donde solventas la duda que planteabas en el primero.
Bien, solo falta seguir el manual para conseguir lo que uno quiere.

En cuanto a tu código, he de decirte que me ha gustado. Me ha gustado por los recursos que has utilizado.
Yo he mamado Java en este lugar y tu estilo de programación no lo había visto todavía. Presumo que lo has aprendido en otro sitio. Solo puedo decir que me gusta por lo novedoso.

Yo no soy ningún experto, pero aún así voy a darte mi opinión.
1º Aunque la clase Cantante Famoso para este ejercicio no necesita más de lo que le has dado (atributos y getters).
Para salir a la palestra y servir para todo, no le sobraría un constructor vacío y otro con parámetros, tampoco estaría de más adjuntarle los setters y por pedir, que no falte el método toString.
Ah, y para darle versatilidad, hacer la clase independiente guardándola en un archivo distinto.
Con estos aditamentos, una clase sirve lo mismo para una pelea de barrio como para ir a la guerra de Irak.

2º En la clase ListaCantantesFamosos además de sus atributos y los métodos para gestionar la lista has colocado el método sobrecargado añadirCantantes. De este método, yo habría colocado el que no tiene parámetros (el que lee de teclado) en la clase del main. Así le quitaría responsabilidades a la clase ListaCantantesFamosos y se la devolvería al main para que sea esta clase la que dirija el cotarro.

3º No se si esto influiría en la eficiencia, pero en algún lugar para añadir un nuevo cantante a la lista utilizas hasta cuatro instrucciones, cuando se podría hacer con una, ejem.
listaCantantes.add(new CantanteFamoso(nombre, discoSuperventas));
Para esto claro haría falta la existencia de un construtor con parámetros.

Post data: Bienvenido a aprenderaprogramar, espero que te quedes en enseñaraprogramar

Saludos de toni de la a pe erre

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Hola, mis comentarios: no me parece muy adecuado declarar un atributo de clase después de haber escrito el código de una clase interna (me refiero a CantanteFamoso nuevoCantante  en ListaCantantesFamosos).

Tampoco me parece muy adecuado declarar CantanteFamoso como clase interna de ListaCantantesFamosos, ya que no le das visibilidad desde fuera. Como clase interna en principio sólo deberíamos declarar clases que exclusivamente van a ser usadas por las clases envolventes, pero en este caso no parece muy lógico hacerlo. Un cantante famoso puede existir tanto por sí mismo como en una lista, por lo tanto no es lógico que quien únicamente pueda manejar un cantante famoso sea la lista.

De resto veo el código bien trabajado y el método main muy compacto (perfecto).

En general diría que muy bien, pero con esos detalles mejorables.

Salu2

Gilding

  • Sin experiencia
  • *
  • Mensajes: 44
    • Ver Perfil
Hola! muy buenas a todos.

No te acostarás sin aprender algo nuevo... no sabía que se podía crear una clase dentro de otra clase :o. Estoy empezando con Java en particular y con la POO en general, asi que hay muchisimas cosas que todavía desconozco ;D. Eso sí, la respuesta de Ogramar me ha aclarado bastantes dudas al respecto.

Sin embargo, en su segundo post, me ha surgido otra duda al ver el código del compañero "palotes" (jajaja, que bueno el nick). Él declara el campo o atributo "iterador", que entiendo es una lista de tipo "Iterator", ¿no?. Hasta ahí todo bien (aunque todavía no conozco este tipo de objetos), mi duda es: ¿Por qué no lo inicializa en el constructor?. Estoy en esta parte del curso de iniciación de Java, y dicho curso indica que se deben inicializar todos los atributos de la clase en el constructor. ¿Ha sido un lapsus del compañero "palotes"? ¿Este tipo de objeto no se inicializa como los demás... y de ser así, por qué? ¿Hay más tipos de objetos o algún tipo de objeto que no se debe inicializar?.


Muchas gracias a todos por vuestras respuestas, que seguro serán de gran ayuda.



Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Hola Gilding, en programación te encontrarás muchas variantes y formas de hacer las cosas. Los Iterator se estudian en el curso en entregas más avanzadas, así que más adelante te irás familiarizando con ellos. De momento puedes pensar que la regla general es que todos los atributos se deben inicializar en el constructor, pero sabiendo lo que haces, puedes no seguir al pie de la letra esa regla general. En el caso de los Iterator, son objetos que se usan para recorrer colecciones, por ello el momento adecuado para inicializarlos es justo antes de hacer uso de ellos. Otra opción es no ponerlo como atributo, sino como variable local a un método. En resumen, hay reglas generales pero también hay excepciones a las reglas generales  ;D Salu2

palote el de los pericos

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 4
    • Ver Perfil
Hola de nuevo. Lo primero daros las gracias por contestar y por los consejos. Sí que es verdad, toni, que había pensado en modificar la clase para crear los objetos en una sola línea, a ver si puedo mañana que he estado muy liado y no he podido.

Muchas gracias por el consejo sobre las clases internas, ogramar. Había visto que se usan para la creación de listas enlazadas "a pelo", haciendo el código a mano. Lo que no sabía es lo del tema de usarlas sólo cuando las usen en exclusiva las clases envolventes y claro, los objetos CantanteFamoso deben de poder usarse en cualquier parte.

Me alegra saber que aunque me queda mucho por aprender, voy haciendo las cosas medianamente bien y por supuesto que nos seguiremos viendo por aquí por el foro.
A ver si mañana tengo un poco de tiempo y me pongo a hacer experimentos con multimap y con algo que llaman "aggregate operations", espero que el ordenador no explote  ;D

Un saludo.

Gilding

  • Sin experiencia
  • *
  • Mensajes: 44
    • Ver Perfil
Muchas gracias por tú aclaración Ogramar, me ha resultado de gran utilidad y tendré en cuenta tus consejos en el futuro.

Un saludo! ;D

 

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