-

[RISOLTO] Stampa di un ArrayList in Java

Stato
Discussione chiusa ad ulteriori risposte.
#1
Salve è la prima volta che uso ArrayList e ne devo fare una di oggetti "Libro" che ho dichiarato così "ArrayList<Libro> catalogo = new ArrayList<Libro>();"
La classe Libro contiene tre campi:
- Autore
- Titolo
- Prezzo
Con uno switch ho creato un menu e una delle voci è quella della stampa dell'ArrayList.
Per la stampa ho fatto questo codice :
Java:
if(catalogo.size()>0)
{
    for(int i=0 ; i<catalogo.size(); i++)
    {
        nuovoL = catalogo.get(i);
        System.out.println("Il titolo del libro e': " + nuovoL.getTitolo());
        System.out.println("L'autore del libro e': " + nuovoL.getAutore());
        System.out.println("Il prezzo del libro e': " + nuovoL.getPrezzo());
        System.out.println();
    }
}
else
    System.out.println("Il catalogo è vuoto");
Con questo codice estraggo il singolo oggetto di tipo "Libro" e stampo campo per campo.
Il problema è che quando stampo, il numero dei libri è giusto, ma viene stampato solo l'ultimo libro inserito.
Quindi se inserisco 2 libri prima A e poi B, mi stampa due volte B...
Ho pensato che il problema fosse l'inserimento ma usando un altro metodo di ricerca l'altro libro è presente.
E se stampo dopo aver fatto la ricerca mi stampa N volte solo il libro ricercato...
 
Ultima modifica da un moderatore:
#2
Ridefinisci il metodo toString() nella classe libro, in modo che faccia la stampa di un singolo libro; a prescindere da dove metterai il libro è conveniente, in quanto potrai stampare un libro con la singola istruzione
Java:
System.out.println(lib); // con lib di classe Libro ovviamente
dall'interno di qualsiasi metodo.
Poi prova il seguente ciclo (qualcuno lo chiama for-each, ossia "per ciascun"):
Java:
for(Libro lib : catalogo) // per ogni libro in (:) catalogo - i due punti rappresentano "in"
   System.out.println(lib);
 
Mi Piace: Alessandro001

DispatchCode

Utente Attivo
514
306
Hardware Utente
CPU
Intel i7 6700HQ, 2.60Ghz, 4 core 8 threads
Scheda Madre
Asustek
Hard Disk
Hitachi 7200 rpm, 1TB
RAM
16GB DDR4 (2 slot su 4)
Scheda Video
Nvidia Geforce GTX 960M, 4GB
Scheda Audio
Realtek
Sistema Operativo
Windows 10 64bit
#4
Ma se volessi prelevare il libro e stampare il singolo campo?
Non si potrebbe fare come cosa?
In questo modo come mi verrebbe la stampa
Non mi verrebbe una cosa tipo
"il titolo è :" titolo
"l'autore è :" autore

Inviato da SNE-LX1 tramite App ufficiale di Tom\'s Hardware Italia Forum
Il metodo toString() è ereditato da Object, ed è la rappresentazione dell' oggetto. Si tratta di far tornare una stringa il cui formato lo decidi tu.
 
#5
Ridefinisci il metodo toString() nella classe libro, in modo che faccia la stampa di un singolo libro; a prescindere da dove metterai il libro è conveniente, in quanto potrai stampare un libro con la singola istruzione
Java:
System.out.println(lib); // con lib di classe Libro ovviamente
dall'interno di qualsiasi metodo.
Poi prova il seguente ciclo (qualcuno lo chiama for-each, ossia "per ciascun"):
Java:
for(Libro lib : catalogo) // per ogni libro in (:) catalogo - i due punti rappresentano "in"
   System.out.println(lib);
Quando uso questo codice mi stampa un codice corrispondente al libro, non mi stampa i campi come vorrei.
E se facessi la prelevazione di catalogo.get(i); con i sempre uguale a 0, il valore cambia.
Nel senso, se metto A e poi B, catalogo.get(0); prima vale A e dopo vale B quando dovrebbe valere sempre A...
Poi come dovrei fare per richiamare nel main il metodo toString() sulla singola cella dell'arraylist?
Nella stampa continua a stamparmi solo l'ultimo inserito ma facendo una ricerca di elementi presenti nell'arraylist quelli sono presenti...
Poi se volessi prelevare un singolo libro nella iesima posizione e successivamente stamparlo nel main non sarebbe comunque fattibile? Eppure quando lo prelevo con
Java:
nuovoL = catalogo.get(i);
mi stampa sempre lo stesso libro ovvero l'ultimo inserito
Post unito automaticamente:

Ho trovato l'errore ed era nel caricamento
Prima facevo così:
Java:
Libro nuovoL = new Libro();
nuovoL.setAutore(MyInput.leggiStringa("Inserire l'autore del libro"));
nuovoL.setTitolo(MyInput.leggiStringa("Inserire il titolo del libro"));
nuovoL.setPrezzo(MyInput.leggiVal("Inserire il prezzo del libro",1,20));
catalogo.add(nuovoL);System.out.println(catalogo.get(0).toString());
e non andava, ora va dichiarando nuovoL ad ogni inserimento:

Java:
Libro nuovoL = new Libro(MyInput.leggiStringa("Inserire l'autore del libro"),MyInput.leggiStringa("Inserire il titolo del libro"),MyInput.leggiVal("Inserire il prezzo del libro",1,20));
catalogo.add(nuovoL);System.out.println(catalogo.get(0).toString());
Anche se la ricerca continua a non funzionare dicendo che l'elemento non è mai presente nell'ArrayList usando il metodo contains...
 
Ultima modifica:
#7
Catalogo lo dichiaro con
Java:
ArrayList catalogo = new ArrayList();
E per valorizzare la singola cella facevo
Java:
catalogo.add(nuovoL);
Dove nuovoL è stato dichiarato solo una volta
Dichiarandolo più volte funziona e non capisco perché...
Non basterebbe dichiararlo una volta sola?
 
Ultima modifica:
#10
Non hai capito il suggerimento: toString() deve essere ridefinito dentro la classe Libro;
DOPO averlo ridefinito la stampa si può fare con la solita System.out.println
il formato della stampa lo decidi tu dentro il toString() ridefinito
dopo potrai usare il for-each per l'ArrayList.
Ti allego un codice di esempio, è più facile a farsi che a dirsi;
guarda come ho fatto il toString() nella classe Libro, poi modificalo come più ti piace.
Complila ed esegui il seguente codice:
Java:
/** Semplice classe per un Libro. */
import java.util.ArrayList;
public class Libro
{
    private String autore;
    private String titolo;
    private double prezzo;

    public Libro(){} // costruttore vuoto

    public Libro(String aut, String tito) {
        setAutore(aut);
        setTitolo(tito);
    }

    public Libro(String aut, String tito, double p) {
        this(aut, tito);
        setPrezzo(p);
    }

    public void setAutore(String aut){ autore = aut; }
    public void setTitolo(String tito){ titolo = tito; }
    public void setPrezzo(double p){ prezzo = p; }

    public String getTitolo(){ return titolo; }
    public String getAutore(){ return autore; }
    public double getPrezzo(){ return prezzo; }

    /** Ridefinisce to String().
     * @return    la stringa da stampare con System.out.println(lib) con lib di classe Libro
     */
    public String toString(){
        return "Titolo: "+getTitolo()+"\nAutore: "+ getAutore()+"\nPrezzo: euro "+getPrezzo();
    }

    public static void main(String[] args) {
        Libro libr = new Libro("Arthur Block", "La legge di Murphy", 8.95);
        System.out.println("\nStampo singolo libro con System.out.println():");
        System.out.println("------------------------------");
        System.out.println(libr);
        // costruisco un catalogo ..
        ArrayList<Libro> catalogo = new ArrayList<Libro>();
        catalogo.add(libr);
        catalogo.add( new Libro("Dante Alighieri", "La divina Commedia", 40.0) );
        catalogo.add( new Libro("Alessandro Manzoni", "I Promessi Sposi", 25.0) );
        catalogo.add( new Libro("Herman Melville", "Moby Dick", 30.0) );
        System.out.println("\nStampo un catalogo usando for-each");
        for(Libro lib : catalogo){
            System.out.println("------------------------------");
            System.out.println(lib);
        }
    }
}
Ovviamente se vuoi stampare o solo l'autore, o solo il prezzo, o solo il titolo (o una qualsiasi altra combinazioni di questi) userai i metodi get e set in modo opportuno
L'output del programma precedente è
Codice:
Stampo singolo libro con System.out.println():
------------------------------
Titolo: La legge di Murphy
Autore: Arthur Block
Prezzo: euro 8.95

Stampo un catalogo usando for-each
------------------------------
Titolo: La legge di Murphy
Autore: Arthur Block
Prezzo: euro 8.95
------------------------------
Titolo: La divina Commedia
Autore: Dante Alighieri
Prezzo: euro 40.0
------------------------------
Titolo: I Promessi Sposi
Autore: Alessandro Manzoni
Prezzo: euro 25.0
------------------------------
Titolo: Moby Dick
Autore: Herman Melville
Prezzo: euro 30.0
 
Ultima modifica:
#11
Non hai capito il suggerimento: toString() deve essere ridefinito dentro la classe Libro;
DOPO averlo ridefinito la stampa si può fare con la solita System.out.println
il formato della stampa lo decidi tu dentro il toString() ridefinito
dopo potrai usare il for-each per l'ArrayList.
Ti allego un codice di esempio, è più facile a farsi che a dirsi;
guarda come ho fatto il toString() nella classe Libro, poi modificalo come più ti piace.
Complila ed esegui il seguente codice:
Java:
/** Semplice classe per un Libro. */
import java.util.ArrayList;
public class Libro
{
private String autore;
private String titolo;
private double prezzo;

public Libro(){} // costruttore vuoto

public Libro(String aut, String tito) {
setAutore(aut);
setTitolo(tito);
}

public Libro(String aut, String tito, double p) {
this(aut, tito);
setPrezzo(p);
}

public void setAutore(String aut){ autore = aut; }
public void setTitolo(String tito){ titolo = tito; }
public void setPrezzo(double p){ prezzo = p; }

public String getTitolo(){ return titolo; }
public String getAutore(){ return autore; }
public double getPrezzo(){ return prezzo; }

/** Ridefinisce to String().
* @return la stringa da stampare con System.out.println(lib) con lib di classe Libro
*/
public String toString(){
return "Titolo: "+getTitolo()+"\nAutore: "+ getAutore()+"\nPrezzo: euro "+getPrezzo();
}

public static void main(String[] args) {
Libro libr = new Libro("Arthur Block", "La legge di Murphy", 8.95);
System.out.println("\nStampo singolo libro con System.out.println():");
System.out.println("------------------------------");
System.out.println(libr);
// costruisco un catalogo ..
ArrayList catalogo = new ArrayList();
catalogo.add(libr);
catalogo.add( new Libro("Dante Alighieri", "La divina Commedia", 40.0) );
catalogo.add( new Libro("Alessandro Manzoni", "I Promessi Sposi", 25.0) );
catalogo.add( new Libro("Herman Melville", "Moby Dick", 30.0) );
System.out.println("\nStampo un catalogo usando for-each");
for(Libro lib : catalogo){
System.out.println("------------------------------");
System.out.println(lib);
}
}
}
Ovviamente se vuoi stampare o solo l'autore, o solo il prezzo, o solo il titolo (o una qualsiasi altra combinazioni di questi) userai i metodi get e set in modo opportuno
L'output del programma precedente è
Codice:
Stampo singolo libro con System.out.println():
------------------------------
Titolo: La legge di Murphy
Autore: Arthur Block
Prezzo: euro 8.95

Stampo un catalogo usando for-each
------------------------------
Titolo: La legge di Murphy
Autore: Arthur Block
Prezzo: euro 8.95
------------------------------
Titolo: La divina Commedia
Autore: Dante Alighieri
Prezzo: euro 40.0
------------------------------
Titolo: I Promessi Sposi
Autore: Alessandro Manzoni
Prezzo: euro 25.0
------------------------------
Titolo: Moby Dick
Autore: Herman Melville
Prezzo: euro 30.0
Grazie mille per la risposta e la disponibilità.
Una domanda
Facendo
Java:
System.out.println(lib);
con lib di classe libro mi stampa un codice strano
Invece facendo cosi
Java:
System.out.println(lib.toString());
Non ci sono problemi perché tanto l'output me lo gestisco nel metodo toString()
 
#12
lib.toString() converte esplicitamente in stringa un oggetto di classe libro;
ma se hai ridefinito il metodo toString() DENTRO la definizione di classe Libro tale conversione deve essere automatica, non hai guardato il mio codice? In particolare nel main trovi le istruzioni
Java:
Libro libr = new Libro("Arthur Block", "La legge di Murphy", 8.95);
...
System.out.println(libr);
dove libr è di classe libro e viene stampato senza alcun problema.
Lo "strano codice" che risulta a te è un codice hash: SE NON VIENE RIDEFINITO opportunamente toString(), Java stampa il codice del riferimento dell'oggetto passata alla println(), una cosa del tipo Nome-classe@un-numero; cioè se tu stampi
System.out.println(lib) senza aver ridefinito toString() come metodo interno alla classe libro, ti stampa quel codice. Se hai quel risultato il tuo codice non è stato fatto bene.
Magari posta il tutto tuo codice così vediamo meglio.
 
#13
lib.toString() converte esplicitamente in stringa un oggetto di classe libro;
ma se hai ridefinito il metodo toString() DENTRO la definizione di classe Libro tale conversione deve essere automatica, non hai guardato il mio codice? In particolare nel main trovi le istruzioni
Java:
Libro libr = new Libro("Arthur Block", "La legge di Murphy", 8.95);
...
System.out.println(libr);
dove libr è di classe libro e viene stampato senza alcun problema.
Lo "strano codice" che risulta a te è un codice hash: SE NON VIENE RIDEFINITO opportunamente toString(), Java stampa il codice del riferimento dell'oggetto passata alla println(), una cosa del tipo Nome-classe@un-numero; cioè se tu stampi
System.out.println(lib) senza aver ridefinito toString() come metodo interno alla classe libro, ti stampa quel codice. Se hai quel risultato il tuo codice non è stato fatto bene.
Magari posta il tutto tuo codice così vediamo meglio.
Quindi ridefinendo meglio il metodo toString() e scrivendo
Java:
System.out.println(lib);
con lib di classe libro, automaticamente richiama quel metodo?
Io per fare l'output in quel modo ho richiamato il metodo toString() sull'oggetto lib.
È sbagliato?
 
Ultima modifica:
#14
Non è la chiamata ad essere sbagliata, il fatto è che è assolutamente impossibile che le cose vadano come dici tu.
Prendi il codice Java precedente che ti ho postato (ho scritto tutta la classe compreso un main di prova), fatti un copia incolla in un file di testo e salvalo come Libro.java
Compila ed esegui, vedrai che funziona. Ti ho chiesto di postare il TUO codice (tutto), se non lo fai come faccio a verificare quello che dici?
 
Mi Piace: Alessandro001
#15
Non è la chiamata ad essere sbagliata, il fatto è che è assolutamente impossibile che le cose vadano come dici tu.
Prendi il codice Java precedente che ti ho postato (ho scritto tutta la classe compreso un main di prova), fatti un copia incolla in un file di testo e salvalo come Libro.java
Compila ed esegui, vedrai che funziona. Ti ho chiesto di postare il TUO codice (tutto), se non lo fai come faccio a verificare quello che dici?
Grazie per l'aiuto, mi scuso se a volte non ho capito cosa volessi dire.
Ho appena riprovato e l'errore era causato dalla definizione errata del metodo toString();
Un ultima domanda riguardante la ricerca di un oggetto all'interno di un ArrayList.
Per la ricerca di un oggetto nell'ArrayList uso il metodo indexOf() in questo modo:
Java:
if(catalogo.size()>0)
                    {
                        Libro nuovoL = new Libro("Dante","Divina Commedia",10);
                        if(catalogo.indexOf(nuovoL)>=0) System.out.println("Libro presente nella lista");
                        else
                        System.out.println("Libro non presente nella lista");
                    }
                        else
                        System.out.println("Il catalogo è vuoto");
Ho pensato che fare un controllo sul valore restituito dall'indexOf fosse corretto dato che restituisce la posizione in cui l'oggetto è presente.
Il problema è che restituisce sempre "Libro non presente nella lista" e non capisco il motivo.
Forse perchè l'indexOf compara i puntatori degli oggetti e non i singoli campi...
 
Stato
Discussione chiusa ad ulteriori risposte.

Entra

Guarda il video live di tomshardwareita su www.twitch.tv