Visualizzazione dei risultati da 1 a 9 su 9
  1. #1

    Metodo add() di ArrayList non aggiunge

    Salve, ho un problema credo semplice in un contesto un po' complicato da spiegare.
    Sto simulando un carrello di acquisti di libri e DVD, ogni articolo è dotato di titolo e prezzo, rispettivamente String e double. Riesco a visualizzare correttamente il totale ma non l'elenco dei titoli acquistati, che vanno a popolare un ArrayList di String.
    Libro.java (DVD.java è analogo...)
    codice:
    class Libro implements ElementiCarrello {
        private String titolo;
        private double prezzo;
        
        public Libro(String titolo, double prezzo) {
    
            this.titolo = titolo;
            this.prezzo = prezzo;
        }
        
        @Override
        public String getTitolo() {
            return titolo;
        }
        
        @Override
        public double getPrezzo() {
            return prezzo;
        }
        
        @Override
        public void accetta(Visitor visitor) {
            visitor.visita(this);
        }
    }
    L'interface ElementiCarrello.java non fa altro che dichiarare i metodi di cui qui c'è l'override.
    Ho poi una interface Visitor.java con la quale predisporre le chiamate ai metodi in base all'articolo acquistato:
    codice:
    public interface Visitor {
        public void visita(Libro libro);
        public void visita(DVD dvd);
    }
    Quindi la classe CarrelloTotale.java, dove la dimensione dell'ArrayList resta zero e quindi non mi trova nulla col for...
    codice:
    import java.util.ArrayList;
    
    
    class CarrelloTotale implements Visitor {
        private double totale;
        private Carrello carrello;
        private ArrayList<String> titoli = new ArrayList<String>();
        
        public CarrelloTotale(Carrello carrello) {
            this.carrello = carrello;
            this.totale = 0.0;
        }
        
        public void visita(Libro libro) {
            titoli.add(libro.getTitolo()); // non aggiunge
            totale += libro.getPrezzo(); // aggiorna il totale
        }
        
        public void visita(DVD dvd) {
            titoli.add(dvd.getTitolo()); // non aggiunge
            totale += dvd.getPrezzo(); // aggiorna il totale
        }
        
        public void getTitoli() {
            System.out.println("Titoli acquistati: " + titoli.size());
            for (String tit : titoli) {
                System.out.println(tit);
            }
        }
    La parte di gestione del totale l'ho omessa poiché funziona tranquillamente.
    Vorrei capire perché i metodi visita() non aggiungono i titoli all'ArrayList. Grazie.
    Spero che il problema sia esposto chiaramente.

  2. #2
    Aggiornamento: facendo debugger sul programma, le String dei titoli arrivano fino all'argomento dei metodi visita(), volendo si riescono anche a stampare, ma non ad aggiungere all'ArrayList dedicato. Non funziona nemmeno aggiungendo una String direttamente dentro add() senza invocare altro.
    In altre parole libro.getTitolo() funziona ma non passa il suo return ad add()!

  3. #3
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da Gas75 Visualizza il messaggio
    Vorrei capire perché i metodi visita() non aggiungono i titoli all'ArrayList.
    Il add() sicuramente aggiunge, NON penso proprio che sia quello il problema. Mi viene da pensare invece altro riguardo CarrelloTotale. CHI istanza l'oggetto CarrelloTotale? Ne hai solo uno?
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  4. #4
    CarrelloTotale è istanziato dal main(), questa la classe di partenza (gli elementi andrebbero aggiunti da terminale e non da codice, ma mi sto concentrando appunto sul pattern e mi sono arenato con i titoli):
    codice:
    public class TestVisitor {
        public static void main(String args[]) {
            Libro libro = new Libro("Il segno del comando", 7.99);
            DVD dvd = new DVD("Il mistero dei Templari", 12.10);
            Carrello carrello = new Carrello();
            carrello.add(libro);
            carrello.add(dvd);
            CarrelloTotale carrelloTotale = new CarrelloTotale(carrello);
            carrelloTotale.getTitoli();
            System.out.println("Totale = " + carrelloTotale.getTotale());
        }
    }

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da Gas75 Visualizza il messaggio
    CarrelloTotale è istanziato dal main(), questa la classe di partenza (gli elementi andrebbero aggiunti da terminale e non da codice
    codice:
            Carrello carrello = new Carrello();
            carrello.add(libro);
            carrello.add(dvd);
    E cosa fa Carrello? Non l'hai postato.

    Inoltre considera che in CarrelloTotale l'oggetto Carrello che il costruttore riceve poi NON viene usato.
    codice:
    class CarrelloTotale implements Visitor {
        private double totale;
        private Carrello carrello;   // ma poi questo NON viene usato nei metodi ....
        private ArrayList<String> titoli = new ArrayList<String>();
        
        public CarrelloTotale(Carrello carrello) {    // ok, riceve Carrello
            this.carrello = carrello;   // ok, assegna il Carrello
            this.totale = 0.0;
        }

    quindi?

    Quote Originariamente inviata da Gas75 Visualizza il messaggio
    ma mi sto concentrando appunto sul pattern e mi sono arenato con i titoli):
    Che c'entrano i pattern? Se ti riferisci all'approccio del Visitor in Libro/DVD, è solo un "girare" le chiamate in maniera differente. Ma in realtà non sarebbe nemmeno strettamente necessario.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  6. #6
    Il programma era partito con lo scopo di confrontare il totale calcolato in modo "tradizionale" e col pattern Visitor, poi ho pensato di modificarlo togliendo il calcolo del totale "tradizionale" e aggiungendo alla modalità col pattern l'elenco degli elementi acquistati.
    Nel main ci sarebbe infatti anche
    codice:
    System.out.println("Totale = " + carrello.getTotale());
    Carrello.java eccolo qua:
    codice:
    import java.util.List;
    import java.util.ArrayList;
    
    
    class Carrello {
        private List<ElementiCarrello> elementi;
        
        public Carrello() {
            elementi = new ArrayList<>();
        }
        
        public void add(ElementiCarrello elemento) {
            elementi.add(elemento);
        }
        
        // funziona ma poco "realistico", si complica se si vogliono introdurre offerte su alcuni tipi di articoli
        public double getTotale() {
            double totale = 0.0;
            for (ElementiCarrello e : elementi) {
                totale += e.getPrezzo(); // da Libro.java e DVD.java
            }
            return totale;
        }
        
        public List<ElementiCarrello> getElementi() {
            return elementi;
        }
    }
    Il pattern non c'entra col problema, infatti nel titolo della discussione parlo dell'add() di ArrayList.
    Il pattern è stato il pretesto per produrre questo codice, il discorso pattern sarebbe esaurito se riuscissi a passare i titoli oltre ai prezzi.

  7. #7
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da Gas75 Visualizza il messaggio
    Il programma era partito con lo scopo di confrontare il totale calcolato in modo "tradizionale" e col pattern Visitor, poi ho pensato di modificarlo togliendo il calcolo del totale "tradizionale" e aggiungendo alla modalità col pattern l'elenco degli elementi acquistati.
    Ok ma forse non mi sono spiegato bene.

    Nel main fai:
    codice:
            Libro libro = new Libro("Il segno del comando", 7.99);
            DVD dvd = new DVD("Il mistero dei Templari", 12.10);
            Carrello carrello = new Carrello();
            carrello.add(libro);
            carrello.add(dvd);

    Quindi ora i due articoli li stai aggiungendo nell'oggetto Carrello.
    codice:
            CarrelloTotale carrelloTotale = new CarrelloTotale(carrello);
            carrelloTotale.getTitoli();
            System.out.println("Totale = " + carrelloTotale.getTotale());

    Qui stai passando il Carrello al CarrelloTotale. Ma attenzione, come dicevo prima, il Carrello NON LO USI (perlomeno per quanto ho visto postato) in CarrelloTotale.
    Quindi i visita() di CarrelloTotale NON sono stati invocati, pertanto il getTotale() non può trovare nulla.

    E comunque questa dualità Carrello e CarrelloTotale non ha molto senso ...
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  8. #8
    Devo aver fatto confusione nel passare da un modo all'altro di calcolo del totale (Carrello simula il classico carrello della spesa, CarrelloTotale simula la cassa che emette lo scontrino), vedendo che in CarrelloTotale faceva getTotale(), gli ho aggiunto l'istruzione add() sull'altro parametro dell'elemento.

  9. #9
    Risolto!
    Ho cambiato getTitoli() in CarrelloTotale, ribattezzato Cassa perché più significativo:
    codice:
    public void getTitoli() {
    	for (ElementiCarrello ec : carrello.getElementi()) {
    		ec.accetta(this);
    	}
    	System.out.println("Titoli acquistati: " + titoli.size());
    	for (String tit : titoli) {
    		System.out.println(tit);
    	}
    }
    Ora sto valutando di unire getTitoli() e getTotale() in un unico metodo, dato che il for è identico, magari trasferendo in Cassa i println.
    Grazie per gli spunti di riflessione, mi ero fissato su add()...

Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.