Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 15
  1. #1
    Utente di HTML.it
    Registrato dal
    Dec 2013
    Messaggi
    24

    [Java] Problema con gli iterator e la serializzazione

    Salve a tutti ho iniziato a studiare java da un po di tempo e per "allenamento studio" sto provando a scrivere una piccola applicazione di gestione di un archivio.
    La mia idea era che l'archivio potesse essere serializzato e salvato in memoria per poi deserializzarlo di volta in volta per effettuare dell operazioni su di esso aggiunta e rimozione di voci all'archivio e stampa su pdf degli elementi dell archivio...per la aggiunta e la ricerca nessun problema il mio problema nasce con la rimozione..
    questa sono le mie classi per la gestione dell archvio
    codice:
    package Archivio; 
    
    import com.itextpdf.text.BaseColor;
    import java.util.ArrayList;
    import java.io.*;
    import com.itextpdf.text.pdf.PdfWriter;
    import com.itextpdf.text.Document;
    import com.itextpdf.text.DocumentException;
    import com.itextpdf.text.Paragraph;
    import com.itextpdf.text.Font;
    import com.itextpdf.text.Font.FontFamily;
    import java.util.Collections;
    import javax.swing.JTextArea;
    import java.util.Iterator;
    public class Archivio implements Serializable {
         private static final long serialVersionUID= 1L;
        protected ArrayList<VoceArchivio> archivio;
        public Archivio(){
        archivio= new ArrayList<VoceArchivio>();
        }
        /**
         * metodo per inserire un elemento nell archivio
         * @param v un elemento per  l'archivio
         */
        public void addVoceArchivio(VoceArchivio v){
            archivio.add(v);
        } 
        /**
         * metodo per eliminare un elemento dall archivio
         *  @param v elemento da eliminare
         */
        public void removeVoceArchivio(VoceArchivio v){
            Iterator<VoceArchivio> it = archivio.iterator();
            while(it.hasNext()){
             VoceArchivio a = it.next();
               if(a.equals(v))
               it.remove();
           }
        }
        
        public void stampaArchivio(String fileArchvio){
            Collections.sort(archivio);
            (...)
        }
    }
    le due classi che serializzano e deserialiazzano l'archvio sono
    codice:
    package Archivio;
    import java.io.*;
    /**
     * Questa classe legge da file e deserializza un archvio inserendo le voci in un archvio 
     */
    public class DeserializzaArchivio {
        private Archivio archivio;
        final String nomeFile="archivio.dat";
         
        public DeserializzaArchivio(){
            
            try{
               ObjectInputStream input = new ObjectInputStream(new FileInputStream(nomeFile));
                archivio =(Archivio) input.readObject();
                input.close();
            }
            catch (FileNotFoundException e) 
            {
                System.out.println("");
            }
            
            catch (IOException e) {
                System.out.println(e);
            }
            catch (ClassNotFoundException e){
                System.out.println(e);
            }
           
        }
        public Archivio getArchivio(){
            return archivio;
        }
    }
    
    
    package Archivio;
    import java.io.*;
    public class SerializzaArchivio {
        final String nomeFile="archivio.dat";
        public  SerializzaArchivio(Archivio archivio){
            ObjectOutputStream output;
            try{
                output = new ObjectOutputStream(new FileOutputStream(nomeFile)); 
                output.writeObject(archivio);
                output.close();
            }
             catch (FileNotFoundException e) 
            {
                System.out.println(e);
            }
            catch (IOException e) {
                System.out.println(e);
            }
        }
    }
    Quando provo l'archivio

    codice:
    package Archivio;
    
    
    public class archvioprova {
        public static void main (String []args){
            CD cd1 = new CD ("provacd1","provacd1",10,true,10,"commento1");
            CD cd2 = new CD ("provacd2","provacd2",10,true,10,"commento2");
            DVD dvd1 = new DVD("provadvd1","prova",10,true,"prova");
            //CD e DVD sono classi derivate della classe padre VoceAchivio non penso serva che posti             //anke il loro codice ma nel caso lo faccio
            Archivio archivio = new Archivio();
            archivio.addVoceArchivio(cd1);
            archivio.addVoceArchivio(cd2);
            archivio.addVoceArchivio(dvd1);
            
            //se applico i metodi senza serializzare l'archvio
            archivio.stampaArchivio("totale");
            archivio.removeVoceArchivio(cd2);
            archivio.stampaArchivio("parziale");
            //in questo caso fa quello che ho in mente cioè elimina cd2 e quando creo
            //il pdf parziale il cd2 non risulta + nell archvio
            
            //se invece prima serializzo
            SerializzaArchivio sa = new SerializzaArchivio(archivio);
            DeserializzaArchivio da = new DeserializzaArchivio();
            da.getArchivio().stampaArchivio("tot");
            //fin qui tutto bene
            da.getArchivio().removeVoceArchivio(cd2);
            da.getArchivio().stampaArchivio("parz");
            //quando creo "parz"  e lo apro  in questo caso non succede niente!!(il cd2 non viene cancellato)
            }
    }
    Credo che il problema sia in un "conflitto" tra gli iterator del metodo removeVoceArchvio e la serializzazione dell archivio spero possiate aiutarmi perchè è un paio di giorni che non riesco a
    trovare una soluzione
    PS scusate sono stato prolisso ma volevo essere chiaro se il post viola qualke regolamento proverò a riscriverlo in maniera + riaussuntiva
    Ultima modifica di kekkuz87; 16-12-2013 a 20:20

  2. #2
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    1,123
    Gli ho dato uno sguardo rapido, ma ho notato questo:

    codice:
        public void removeVoceArchivio(VoceArchivio v){
            Iterator<VoceArchivio> it = archivio.iterator();
            while(it.hasNext()){
             VoceArchivio a = it.next();
               if(a.equals(v))
               it.remove();
           }
        }
    richiama in questo modo remove:

    codice:
    archivio.remove(a);
    Se non funziona posta anche la classe VoceArchivio (che se non erro non l'hai postata).

  3. #3
    Utente di HTML.it
    Registrato dal
    Dec 2013
    Messaggi
    24
    prima di tutto grazie per l'aiuto
    purtroppo non funziona...

    codice:
    package Archivio;
    
    
    import java.io.Serializable;
    
    
    public class VoceArchivio implements Comparable<VoceArchivio>, Serializable {
        
        private static final long serialVersioneUID=1L;
        
        protected String titolo;
        protected String autore;
        protected boolean possesso;
        protected String commento;
    
    
        
        protected VoceArchivio(String titolo, String autore,Boolean possesso,String commento){
            
            this.titolo=titolo;
            this.autore=autore;
            this.possesso=possesso;
            this.commento=commento;
        
        }
    
    
        protected String getAutore(){
            return autore;
        }
       
        protected String getTitolo(){
            return titolo;
        }
          @Override
        public String toString(){ 
           if(possesso)
               return "[T] "+titolo+" [A] "+autore+" "+" é in mio possesso ";
           else
               return "[T] "+titolo+" [A] "+autore+" "+" é stato prestato ";
               
           }
    
    
          public void stampaDati(){
              System.out.println(toString());
          }
    
    
          @Override
        public int  compareTo(VoceArchivio v){
            int result;
            result=titolo.compareTo(v.getTitolo());
            return result;
        }
    }
    
    package Archivio;
    
    
    public class DVD extends VoceArchivio{
        private double durata;
    
    
        public DVD(String unTitolo,String unRegista,double unaDurata,boolean unPossesso,String unCommento ){
            super(unTitolo,unRegista,unPossesso,unCommento);
                    durata=unaDurata;     
        }
        public void setDurata(double durata){
            this.durata=durata;
        }
    
    
        public double getDurata(){
            return durata;
        }
        @Override
        public String toString(){
            return "[DVD] "+super.toString()+" [D] "+durata+" [Com] "+commento; 
        }
        public void StampaDVD(){
            System.out.println(toString());
        }
        
    }
    
    package Archivio;
    
    
    public class CD extends VoceArchivio{
        
        private int numeroBrani;
        private double durata;
    
    
        public CD(String unTitolo, String unAutore, int unNumeroBrani,boolean possesso,
                double unDurata, String unCommento){
            super(unTitolo,unAutore,possesso,unCommento);
            numeroBrani=unNumeroBrani;
            durata=unDurata;
        }
    
    
        public void setNumeroBrani(int numeroBrani){
            this.numeroBrani=numeroBrani;
        }
    
    
        public int getNumeroBrani(){
            return numeroBrani;
        }
    
    
        public void setDurata(double durata){
            this.durata=durata;
        }
    
    
        public double getDurata(){
            return durata;
        }
    
    
        @Override
        public String toString(){
            return "[CD] "+super.toString()+ " [NB] "+numeroBrani+" [D] "+durata+" [Com] "+commento;
        }
    
    
        public void stampaCD(){
            System.out.println(toString());
        }
    }
    ecco la classe VoceArchivio e le due classi derivate CD e DVD

    spero possano essere di aiuto
    Ultima modifica di kekkuz87; 17-12-2013 a 00:55

  4. #4
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    1,123
    Ok, allora fai così

    codice:
        public void removeVoceArchivio(VoceArchivio v){
            Iterator<VoceArchivio> it = archivio.iterator();
            while(it.hasNext()){
             VoceArchivio a = it.next();
               if(a.compareTo(v) == 0) {
                 archivio.remove(a);
               }
             }
         }
    Questo solo SE ti interessa l'uguaglanza del Titolo. Altrimenti usa "(a.getTitolo()).equals(v.getTitolo()) && (a.getAutore().equals(...." etc.
    Oppure crei un apposito metodo in quella classe (o modifichi il compareTo(), che è forse la cosa più ovvia).

    PS: Comunque al posto di Iterator è più comodo un ciclo for-each per scorrere gli elementi.
    Ultima modifica di Patrick Jane; 17-12-2013 a 01:19

  5. #5
    Utente di HTML.it
    Registrato dal
    Dec 2013
    Messaggi
    24
    Niente da fare mi lancia questa eccezione
    codice:
    Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
        at java.util.ArrayList$Itr.next(ArrayList.java:831)
        at Archivio.Archivio.removeVoceArchivio(Archivio.java:56)
        at Archivio.archvioprova.main(archvioprova.java:37)
    Java Result: 1
    quello che proprio non capisco perchè se nella classe archivioprova creo l'archivio e applico il metodo removeVoceArchvio fa quello che deve fare mentre se prima serializzo l 'archvio e poi lo deserializzo il tutto non funziona più non andasse in tutte due i casi capirei ma così non riesco proprio a capirlo

    Cmq ancora grazie per l'aiuto anche a quest'ora...
    Ultima modifica di kekkuz87; 17-12-2013 a 01:39

  6. #6
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    1,123
    Si, ho capito perchè ti restituisce quell'eccezione. Dovrebbe proprio essere causa dell'iteratore e della rimozione dell'elemento. Utilizza pure il tuo codice di prima.

    A questo punto allora il problema è dato dalla serializzazione; una volta deserializzato prova a stampare i dati dell'archivio, vedi se c'è dentro quello che dovrebbe esserci.


    PS: nessun problema, figurati mi spiace non essere giunto alla soluzione, ma non potendolo provare ed avendo qualche pensiero di troppo vado a rilento...

  7. #7
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Il problema è sicuramente dovuto al fatto che nel codice iniziale si vede:

    codice:
    if(a.equals(v))
    mentre nel codice poi postato successivamente di VoceArchivio/DVD/CD, si vede che non c'è un override di equals.
    La serializzazione centra solo di "striscio". Siccome non hai fatto l'override di equals, resta quello in Object che si basa solo sulla "identità" degli oggetti. Fintanto che fai removeVoceArchivio(cd2); utilizzando lo stesso identico oggetto che hai inserito, nessun problema, lo trova (per Object è uguale essendo lo stesso oggetto).
    Ma quando deserializzi, ottieni nuovi oggetti, e visto che hai tenuto il riferimento a cd2 .... questo non lo trova più.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  8. #8
    Utente di HTML.it
    Registrato dal
    Dec 2013
    Messaggi
    24
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Ma quando deserializzi, ottieni nuovi oggetti, e visto che hai tenuto il riferimento a cd2 .... questo non lo trova più.
    Devo dire che + o - era quello ke mi ero immaginato quindi devo fare l'overide di equals nelle 3 classi o mi basta in VoceArchivio??

  9. #9
    Utente di HTML.it
    Registrato dal
    Dec 2013
    Messaggi
    24
    Quote Originariamente inviata da Patrick Jane Visualizza il messaggio

    A questo punto allora il problema è dato dalla serializzazione; una volta deserializzato prova a stampare i dati dell'archivio, vedi se c'è dentro quello che dovrebbe esserci.
    lo fatto e risultano dentro tutti gli elementi dell archvio senza nessun problema

  10. #10
    Utente di HTML.it L'avatar di Alex'87
    Registrato dal
    Aug 2001
    residenza
    Verona
    Messaggi
    5,802
    Quote Originariamente inviata da kekkuz87 Visualizza il messaggio
    Devo dire che + o - era quello ke mi ero immaginato quindi devo fare l'overide di equals nelle 3 classi o mi basta in VoceArchivio??
    Ogni classe su cui chiami equals...
    SpringSource Certified Spring Professional | Pivotal Certified Enterprise Integration Specialist
    Di questo libro e degli altri (blog personale di recensioni libri) | ​NO M.P. TECNICI

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 © 2025 vBulletin Solutions, Inc. All rights reserved.