RISOLTO Stampa di un ArrayList in Java

Stato
Discussione chiusa ad ulteriori risposte.

Alessandro001

Utente Attivo
166
7
CPU
Ryzen 5 1600 3.2GHz
Scheda Madre
MSI B350 Tomahawk
HDD
Seagate ST1000DM010 1 TB
RAM
2X8GB Corsair CMK16GX4M2B3000C15 Vengeance
GPU
RADEON RX 580 NITRO+ Radeon RX 580 8GB GDDR5
Monitor
HP 27FW Monitor 27"
PSU
Cooler Master MasterWatt Lite 700 230V
Case
Aerocool Aero-800
Net
https://www.speedtest.net/result/8773872068.png
OS
Windows 10
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:

BAT

Moderatore
Staff Forum
Utente Èlite
22,902
11,552
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
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
Reazioni: Alessandro001

Alessandro001

Utente Attivo
166
7
CPU
Ryzen 5 1600 3.2GHz
Scheda Madre
MSI B350 Tomahawk
HDD
Seagate ST1000DM010 1 TB
RAM
2X8GB Corsair CMK16GX4M2B3000C15 Vengeance
GPU
RADEON RX 580 NITRO+ Radeon RX 580 8GB GDDR5
Monitor
HP 27FW Monitor 27"
PSU
Cooler Master MasterWatt Lite 700 230V
Case
Aerocool Aero-800
Net
https://www.speedtest.net/result/8773872068.png
OS
Windows 10
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
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,222
1,853
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
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.
 

Alessandro001

Utente Attivo
166
7
CPU
Ryzen 5 1600 3.2GHz
Scheda Madre
MSI B350 Tomahawk
HDD
Seagate ST1000DM010 1 TB
RAM
2X8GB Corsair CMK16GX4M2B3000C15 Vengeance
GPU
RADEON RX 580 NITRO+ Radeon RX 580 8GB GDDR5
Monitor
HP 27FW Monitor 27"
PSU
Cooler Master MasterWatt Lite 700 230V
Case
Aerocool Aero-800
Net
https://www.speedtest.net/result/8773872068.png
OS
Windows 10
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:

Krona

Nuovo Utente
69
36
Per capire devi mettere anche il codice di come valorizzi "catalogo". Probabilmente fai assegnazioni per riferimento al posto di duplicare o creare nuovi oggetti.
 

Alessandro001

Utente Attivo
166
7
CPU
Ryzen 5 1600 3.2GHz
Scheda Madre
MSI B350 Tomahawk
HDD
Seagate ST1000DM010 1 TB
RAM
2X8GB Corsair CMK16GX4M2B3000C15 Vengeance
GPU
RADEON RX 580 NITRO+ Radeon RX 580 8GB GDDR5
Monitor
HP 27FW Monitor 27"
PSU
Cooler Master MasterWatt Lite 700 230V
Case
Aerocool Aero-800
Net
https://www.speedtest.net/result/8773872068.png
OS
Windows 10
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:

Alessandro001

Utente Attivo
166
7
CPU
Ryzen 5 1600 3.2GHz
Scheda Madre
MSI B350 Tomahawk
HDD
Seagate ST1000DM010 1 TB
RAM
2X8GB Corsair CMK16GX4M2B3000C15 Vengeance
GPU
RADEON RX 580 NITRO+ Radeon RX 580 8GB GDDR5
Monitor
HP 27FW Monitor 27"
PSU
Cooler Master MasterWatt Lite 700 230V
Case
Aerocool Aero-800
Net
https://www.speedtest.net/result/8773872068.png
OS
Windows 10

BAT

Moderatore
Staff Forum
Utente Èlite
22,902
11,552
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
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:

Alessandro001

Utente Attivo
166
7
CPU
Ryzen 5 1600 3.2GHz
Scheda Madre
MSI B350 Tomahawk
HDD
Seagate ST1000DM010 1 TB
RAM
2X8GB Corsair CMK16GX4M2B3000C15 Vengeance
GPU
RADEON RX 580 NITRO+ Radeon RX 580 8GB GDDR5
Monitor
HP 27FW Monitor 27"
PSU
Cooler Master MasterWatt Lite 700 230V
Case
Aerocool Aero-800
Net
https://www.speedtest.net/result/8773872068.png
OS
Windows 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 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()
 

BAT

Moderatore
Staff Forum
Utente Èlite
22,902
11,552
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
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.
 

Alessandro001

Utente Attivo
166
7
CPU
Ryzen 5 1600 3.2GHz
Scheda Madre
MSI B350 Tomahawk
HDD
Seagate ST1000DM010 1 TB
RAM
2X8GB Corsair CMK16GX4M2B3000C15 Vengeance
GPU
RADEON RX 580 NITRO+ Radeon RX 580 8GB GDDR5
Monitor
HP 27FW Monitor 27"
PSU
Cooler Master MasterWatt Lite 700 230V
Case
Aerocool Aero-800
Net
https://www.speedtest.net/result/8773872068.png
OS
Windows 10
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:

BAT

Moderatore
Staff Forum
Utente Èlite
22,902
11,552
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
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
Reazioni: Alessandro001

Alessandro001

Utente Attivo
166
7
CPU
Ryzen 5 1600 3.2GHz
Scheda Madre
MSI B350 Tomahawk
HDD
Seagate ST1000DM010 1 TB
RAM
2X8GB Corsair CMK16GX4M2B3000C15 Vengeance
GPU
RADEON RX 580 NITRO+ Radeon RX 580 8GB GDDR5
Monitor
HP 27FW Monitor 27"
PSU
Cooler Master MasterWatt Lite 700 230V
Case
Aerocool Aero-800
Net
https://www.speedtest.net/result/8773872068.png
OS
Windows 10
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

oppure Accedi utilizzando
Discord Ufficiale Entra ora!