Visualizzazione dei risultati da 1 a 9 su 9

Discussione: Vector di oggetti

  1. #1

    Vector di oggetti

    Ciao,nel mio progetto ho le seguenti classi:

    Ho una classe studente:

    codice:
    package scuola;
    
    import java.io.Serializable;
    import java.util.*;
    public class Studente implements Serializable {
    
    	private static final long serialVersionUID = 1L;
    	String cognome;
            String matricola;
            String classe;
    	ArrayList<String> amici= new ArrayList<String>();
    	
    	public String getCognome() {
    		return cognome;
    	}
    
    	public String getClasse() {
    		return classe;
    	}
    
    
    	public double getMatricola() {
    		return dimensione;
    	}
    
    }
    La classe Esegui che contiene il main e vengono fatte tante scelte tra cui quella di caricare i dati:
    codice:
    package scuola;
    
    import java.io.*;
    
    import javax.swing.JOptionPane;
    
    import java.util.*;
    
    public class Esegui {
    
    	public static void main(String[] args) {
    
    		InputStreamReader isr = new InputStreamReader(System.in);
    		BufferedReader br = new BufferedReader(isr);
    		int scelta;
    		String line;
    		ElencoStudenti elstu = new ElencoStudenti();
    		Vector<Studenti> stu = new Vector<Studenti>();
                  //un menu' con le possibile scelte e in base al numero che scrivo eseguo un case
    	      //........
    		try {
    			String risp = new String("si");
    			while (risp.equals("si")) {
    				System.out.println("scelta: ");
    				line = br.readLine();
    				selezione = Integer.parseInt(line);
    
    				switch (scelta) {
    				case 1:
    					........
    
    					break;
    
    				case 2:
    					........
    					break;
    
    				case 3:
    					
    					String filestudenti = JOptionPane
    							.showInputDialog(null,
    									"Inserire il nome del file che contiene gli studenti: ");
    					String fileamici = JOptionPane
    							.showInputDialog(null,
    									"Inserire il nome del file che contiene gli amici: ");
    					String s1 = filestudenti + ".txt";
    					String s2 = fileamici + ".txt";
    					sta=elstu.caricaDati(s1, s2);
    				
    				break;
    				
    				}
    				
    		}
    	
    
    }
    La classe ElencoStudenti
    codice:
    package scuola;
    
    import java.io.*;
    
    import java.util.*;
    
    public class ElencoStudenti extends Aula<Studente> {
    
    	private static final long serialVersionUID = 1L;
    //altri metodi che fanno altre cose
    
    public Vector<Studente> caricaDati(String f1, String f2) {
    		try {
    			BufferedReader reader = new BufferedReader(new FileReader(f1));
    			BufferedReader reader1 = new BufferedReader(new FileReader(f2));
    
    			String riga1 = reader1.readLine();
    
    			String riga = reader.readLine();
    
    			while (riga != null) {
    				Studente s = new Studente();
    				String[] split = riga.split(":");
    				if (split.length != 2) {
    
    					continue;
    				}
    
    				String var = split[0].trim();
    
    				s.cognome = var;
    
    				StringTokenizer tokenizer = new StringTokenizer(split[1], " ");
    
    				while (tokenizer.hasMoreTokens()) {
    					s.matricola = (tokenizer.nextToken().trim());
                                            s.classe = (tokenizer.nextToken().trim());
    					stu.add(s);
    				}
    
    				riga = reader.readLine();
    			}
    
    			reader.close();
    			while (riga1 != null) {
    
    				String[] split1 = riga1.split(":");
    				if (split1.length != 2) {
    
    					continue;
    				}
    
    				String var1 = split1[0].trim();
    				String var2 = split1[1].trim();
    
    				if (!(stu.isEmpty())) {
    					int i = 0;
    					while (i < stu.size()) {
    						if (((String) ((Studente) stu.get(i)).cognome)
    								.equalsIgnoreCase(var1))
    							(((S) sta.get(i)).amici).add(var2);
    						else if (((String) ((Studente) stu.get(i)).cognome)
    								.equalsIgnoreCase(var2))
    							(((Studente) stu.get(i)).amici).add(var1);
    
    						if (i != stu.size())
    							i++;
    					}
    				}
    
    				riga1 = reader1.readLine();
    			}
    
    			reader1.close();
    
    		} catch (IOException e) {
    			System.out.println(e.getMessage());
    		}
    return stu;
    	}
    La classe Aula:
    codice:
    package scuola;
    
    import java.util.Vector;
    
    public abstract class Aula<T> {
    	private static final long serialVersionUID = 1L;
    	Vector<Studente> stu = new Vector<Studente>();
    
    	}
    Il fiile filestudenti.txt è cosi composto:
    Rossi : 00122 3C
    Bianchi : 03453 4B
    ......
    ......

    Il file fileamici.txt è così composto:
    Bianchi : Verdi
    Verdi : Rossi
    Rossi : Neri
    .....
    .....
    In pratica quando leggo il primo file memorizzo nel vettore degli studenti tutti gli studenti e quando leggo il secondo file memorizzo nell'arraylist amici di ogni studente l'amico,in base all'esempio nell'arrylist amici di Rossi dovrà comparire Verdi e Neri.
    La parte di codice che mi da problemi è quella in grassetto cioè quando leggo il secondo file.
    Se stampo il vettore dopo aver letto il primo file mi stampa la lista degli studenti mentre appena leggo il secondo file non mi stampa più niente.Volevo sapere se qualcuno mi può aiutare,in cosa sbaglio?Grazie!!!!

  2. #2
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    Qualche spunto...

    * Classe Studente
    - per i principi di progettazione object-oriented, gli attributi di una classe dovrebbero essere dichiarati "private" e acceduti solo attraverso metodi getter e setter. Personalmente poi, salvo casi eccezionali, sconsiglio sempre l'utilizzo di modificatori di visibilità diversi da "public" e "private";
    - piuttosto che un ArrayList, per l'elenco degli amici mi sembrerebbe più comodo utilizzare un HashSet:
    http://download-llnw.oracle.com/java...l/HashSet.html
    Ti dà la garanzia che non ci siano elementi ripetuti al suo interno.

    * Classe Aula
    - a che serve la dichiarazione "generic" di Aula<T> se poi dentro ci forzi un Vector<Studente>?
    - in realtà, questa strutturazione mi sembra piuttosto inutile: non vale la pena spostare il codice di ElencoStudenti direttamente in questa classe?

    * Classe ElencoStudenti
    - nella lettura dell'elenco degli studenti da file l'utilizzo di StringTokenizer mi sembra ridondante... non è molto più comodo - a seguito di una trim() - utilizzare una nuova split() con separatore il carattere "blank"?
    - in merito al codice grassettato, mi rifaccio a quanto detto per la classe Studente: utilizza un HashSet e ti risolverai molti problemi.

    * Classe Esegui
    -
    codice:
    String risp = new String("si");
    Vorrai scherzare...! Si fa così:

    codice:
    String risp = "si";
    - perchè utilizzi un BufferedReader per leggere la scelta dell'utente? Non è più comodo impiegare anche qua un JOptionPane?

  3. #3
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    Originariamente inviato da desa
    Qualche spunto...

    * Classe Studente
    - per i principi di progettazione object-oriented, gli attributi di una classe dovrebbero essere dichiarati "private" e acceduti solo attraverso metodi getter e setter. Personalmente poi, salvo casi eccezionali, sconsiglio sempre l'utilizzo di modificatori di visibilità diversi da "public" e "private";
    L'unico che può tornare utile è protected, nel caso in cui ti serva un accesso rapido in classi figlie e/o inner o nell'uso di clone, anche se private e poi i getter/setter danno una modellazione migliore (tant'è che alla fine nel 90% dei casi uso quelli)

    Originariamente inviato da desa
    codice:
    String risp = new String("si");
    Non è vietato, solo inefficiente perchè alla fine crei 2 oggetti stringa, il primo che contiene "si" e il secondo che viene creato partendo dal primo e lo vedi poi in risp

    se guardi anche la documentazione dice questo per questo costruttore

    codice:
    public String(String original);

    Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable.

    Ho voluto precisarlo solo perché alla fine non è un errore, ma un uso sbagliato della libreria (e se non si deve usare meglio spiegarlo il motivo)

  4. #4
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    L'unico che può tornare utile è protected, nel caso in cui ti serva un accesso rapido in classi figlie e/o inner o nell'uso di clone, anche se private e poi i getter/setter danno una modellazione migliore (tant'è che alla fine nel 90% dei casi uso quelli)
    Difatti dicevo che era un'opinione personale...

    Ho voluto precisarlo solo perché alla fine non è un errore, ma un uso sbagliato della libreria (e se non si deve usare meglio spiegarlo il motivo)
    Non è un'errore, ma l'utilizzo di String è talmente stra-frequente che l'uso esplicito del costruttore non dovrebbe neppure passare per l'anticamera del cervello. Hai comunque fatto bene a spiegare il perchè è così

  5. #5
    Grazie,dei consigli,ho cambiato le cose che mi avete detto però il problema nella lettura dei file rimane.

    Cosa devo cambiare?
    Appena legge il primo file tutto bene ,quando legge il secondo non mi fà ritornare più il vettore con gli stati.
    Mi potete aiutare!!!!

  6. #6
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    Posso vedere come hai modificato la parte di codice in cui viene letto il secondo file?

  7. #7
    codice:
    public Vector<Studente> caricaDati(String f1, String f2) {
    
    //lettura primo file
    ..............
    //lettura secondo file
    BufferedReader reader1 = new BufferedReader(new FileReader(f2));
    String riga1 = reader1.readLine();
    while (riga1 != null) {
    				String[] split1 = riga1.split(":");
    				if (split1.length != 2) {
    					// Ignoro le righe non ben formattare secondo la sintassi:
    					continue;
    				}
    				// Elimino gli spazi prima e dopo il nome della variabile
    				String var1 = split1[0].trim();
    				String var2 = split1[1].trim();
    				int i = 0;
    				setAmici(stu,var1,var2);
    
    				// Aggiorno la riga (ne leggo una nuova)
    				riga1 = reader1.readLine();
    			}
    			// Chiudo il file
    			reader1.close();
    
    		} catch (IOException e) {
    			System.out.println(e.getMessage());
    		}
    		return stu;
    	}
    Questo è un metodo che ho usato per settare i confini dichiarato prima
    codice:
     
    
    	public void setAmici(Vector<Studente> stu, String s1, String s2) {
    
    		if (!(stu.isEmpty())) {
    			int i = 0;
    			while (i < stu.size()) {
    				if (((String) ((Studente) stu.get(i)).getNome())
    						.equalsIgnoreCase(s1))
    					((Studente) stu.get(i)).setAmici(s2);
    
    				else if (((String) ((Studente) stu.get(i)).getNome())
    						.equalsIgnoreCase(s2))
    					((Studente) stu.get(i)).setAmici(s1);
    
    				if (i != stu.size())
    					i++;
    			}
    		}
    
    	}
    Nella classe Studente ho dichiarato gli attributi privati e ho usato i vari get e set.
    codice:
     
    public class Studente implements Serializable {
    
    	private static final long serialVersionUID = 1L;
    	private String nome;
    	private String matricola;
    	.......
    	private HashSet<String> amici = new HashSet<String>();
    
    	public String getNome() {
    		return nome;
    	}
    
    	public String getmatricola() {
    		return matricola;
    	}
    
    	...........
    
    
    	public HashSet<String> getAmici() {
    		return amici;
    	}
    
    	public void setNome(String n) {
    		nome = n;
    	}
            ..........
    
    	public void setAmici(String a) {
    		amici.add(a);
    	}
    
    }

  8. #8
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    Il codice di lettura del file mi sembra corretto... sei sicuro che non ci sia qualche problema nel suo contenuto? Per verificarlo potresti provare a stampare ogni riga subito dopo averla letta e inoltre all'interno del primo "if", subito prima dell'istruzione "continue".

    Il metodo setAmici() può essere ottimizzato così:

    codice:
    public void setAmici(Vector<Studente> stu, String s1, String s2)
    {
      for (int i = 0; i < stu.size(); i++)
      {
        Studente temp = stu.get(i);
    
        if (temp.getNome().equalsIgnoreCase(s1))
        {
          temp.setAmici(s2);
        }
        else if (temp.getNome().equalsIgnoreCase(s2))
        {
          temp.setAmici(s1);
        }
      }
    
      return;
    }
    Fa esattamente le stesse cose che facevi tu... ma ti evita un sacco di casting che in realtà non servivano a nulla. Potrebbe essere opportuno anche implementare un controllo: se nel vettore di studenti dovesse capitare che trovi A (e lo setti amico di B) ma poi, nello stesso vettore, non trovi B... cosa succede?

  9. #9
    Ciao,grazie sempre dei consigli che mi dai,ho risloto il problema si trattava che il file non si chiudeva e quindi dovevo gestire un'eccezione.
    Comunque con il metodo setConfine setta l'ArrayList confini di ogni stato.

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.