Pagina 2 di 3 primaprima 1 2 3 ultimoultimo
Visualizzazione dei risultati da 11 a 20 su 26
  1. #11
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    42
    Forse non mi sono spiegato bene in precedenza.
    In breve,il problema è il seguente.
    L'obiettivo è eliminare gli enunciati System.out.println per i motivi descritti giustamente da te.
    Allora io prendo in esame il metodo aggiungi():
    codice:
    //Metodo che aggiunge un elemento (vincolo:ogni nominativo deve essere diverso da tutti gli altri)
    	public void aggiungi(String nome,String telefono,String fax){
    		boolean presente = false;
    		for (Persona contatto : contatti){
    			if (nome.equals(contatto.getNome())){
    				System.out.println("Il nome " + nome + " è già presente nella lista");
    				presente = true;
    			}
    		}
    		if (presente == false){
    		Persona contatto = new Persona(nome,telefono,fax);
    		contatti.add(contatto);
    		}
    	}
    Eliminando l'enunciato in blu,l'utente non potrà vedere il messaggio d'errore vero?
    Quindi come fare per far si che questo non accada?

  2. #12
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    42
    Ahia!
    HO RISOLTO!
    Sono stato molto idiota a non considerare che tutti i metodi hanno in comune la ricerca dell'elemento,quindi basta sfruttare quel metodo ed è fatta!
    Ad esempio aggiungi viene molto semplicemente cosi:
    codice:
    //Metodo che aggiunge un elemento
    	public void aggiungi (String nome,String telefono,String fax){
    		Persona contatto = new Persona(nome,telefono,fax);
    		contatti.add(contatto);
    	}
    e nel file di test:
    codice:
    Scanner in1 = new Scanner(System.in);
    		System.out.println("Inserisci nome: ");
    		String nome = in1.nextLine();
    		Persona p = rubr.cercaNome(nome);
    		if (p == null){
    			System.out.println("Inserisci il numero di telefono");
    			String telefono = in.nextLine();
    			System.out.println("Inserisci il numero di fax");
    			String fax = in.nextLine();
    			rubr.aggiungi(nome, telefono, fax);
    		    System.out.println ("L'utente "+ nome+ "è stato aggiunto in rubrica");
    		}
    		else{
    
    		    System.out.println ("L'utente "+ nome+" non può essere aggiunto perchè già presente in rubrica");
    		}

  3. #13
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da onepiece007
    Ad esempio aggiungi viene molto semplicemente cosi:
    codice:
    //Metodo che aggiunge un elemento
    	public void aggiungi (String nome,String telefono,String fax){
    		Persona contatto = new Persona(nome,telefono,fax);
    		contatti.add(contatto);
    	}
    Dal punto di vista concettuale è ancora sbagliato. Anche qui è una questione di "design". Se la tua classe definisce degli "invariant" essi devono essere controllati e rafforzati dall'interno della classe, non dall'esterno.
    Un "invariant" è una affermazione che deve essere sempre vera. Una condizione che non deve mai variare.
    Nella tua classe Rubrica esiste un invariant molto importante, l'hai definito tu: non ci devono essere elementi Persona con lo stesso nome, in pratica non ci devono essere nomi duplicati.

    Questo invariante deve essere garantito dalla classe Rubrica. Ma scrivendo aggiungi() come hai fatto sopra questo non può essere garantito, visto che semplicemente crea l'oggetto Persona e lo aggiunge fregandosene di cosa possa esserci in nome.

    Una soluzione migliore è questa:

    codice:
    public class Rubrica
    {
        private ArrayList<Persona> contatti = new ArrayList<Persona> ();
    
        // ....
    
        public boolean aggiungi (String nome, String telefono, String fax)
        {
            if (cercaNome (nome) != null)
                return false;
    
            contatti.add (new Persona (nome, telefono, fax));
            return true;
        }
    
        public Persona cercaNome (String nome)
        {
            for (Persona persona : contatti)
            {
                if (persona.getNome ().equals (nome))
                    return persona;
            }
    
            return null;
        }
    }
    Poi lo usi semplicemente così:

    codice:
    // ... input di nome, telefono, fax ....
    
    if (rubrica.aggiungi (nome, telefono, fax))
        System.out.println ("L'utente " + nome + " è stato aggiunto in rubrica");
    else
        System.out.println ("L'utente " + nome + " non può essere aggiunto perchè già presente in rubrica");
    Che tra l'altro in questo modo è anche più snello e "pulito".


    Quindi, come vedi, non basta scrivere dei metodi così tanto per fare ma bisogna anche ragionare e pensare in termini di concetti e design.

    Adesso ti faccio una domanda: né la tua classe né la mia classe Rubrica sono "thread-safe". Se si volesse rendere la classe Rubrica thread-safe, nella mia sarebbe molto più facile farlo (garantendo sempre l'invariant) rispetto alla tua. Perché? Prova un po' a pensarci.
    Andrea, Senior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  4. #14
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    42
    RIspondendo alla tua domanda:
    posso dirti innanzittutto che noi il concetto di thread-safe non sappiamo neanche dove abita.Però ho visto un po' su wikipedia il suo significato,e a quanto pare riguarda l'esecuzione di più processi.Però penso che nella tua,sarebbe più facile fare il thread-safe,anche perchè hai garantito l'invariant.Forse a causa di boolean che semplifica le cose?

    Comunque stamane prima di leggere la tua risposta,ho modificato gli altri metodi.Ma a differenza di aggiungi(),CREDO e dico CREDO di aver garantito a mio modo l'invariant.
    Posto il metodo cancella:

    codice:
    //Metodo che cancella un elemento
    	public void cancella(String nome){
    		for (int i = 0;i < contatti.size();i++){
    			Persona scan = contatti.get(i);
    			if(nome.equals(scan.getNome())){
    				contatti.remove(i);
    			}
    		}
    	}
    Qui il controllo c'è eccome!Confermi?
    Anche se il codice si potrebbe rendere più snello e intelligente,magari usando il metodo cercanome come hai fatto per aggiungi().

    Voglio comunque avvisarti,che il nostro corso riguarda la programmazione,quind java è nettamente secondario.Per questo non conosciamo alcuni concetti,terminologie,tecniche raffinate di "java".
    L'obiettivo del corso è avere delle basi di programmazione,attraverso java.
    Però devo ammettere che grazie al tuo aiuto in questo forum,ho (credo) fatto dei passi avanti soprattutto nel capire come vanno progettate le classi in java.

    Approfitto dell'occasione per chiarire un altro mio dubbio.
    Devo riscrivere l'ultimo metodo che consiste nell'ordinare in ordine alfabetico l'elenco.Ma questo non è un problema dato che l'algoritmo è corretto.Il problema è elminare il System.out.println.
    Io ho fatto cosi:
    codice:
    //Metodo che stampa tutte le info di tutti gli elementi della lista (vincolo:in ordine alfabetico)
    public String informazioni(){
    	int i = 0;
    	int j = 0;
    	int k = 0;
    	Persona contatto = contatti.get(i);
    	for (i = 0;i < contatti.size()-1;i++){
    		for (j=0;j<contatti.size()-i-1;j++){
    		if ( contatti.get(j).getNome().compareTo(contatti.get(j+1).getNome()) > 0 ){
    			contatto = contatti.get(j);
    			contatti.set(j, contatti.get(j+1));
    			contatti.set(j+1, contatto);		
    			}
    		}
    	}
    	for (k=0;k < contatti.size();k++){
    		return contatti.get(k).getInfo();
    	}
    	return null;
    }
    Sono cosciente del fatto che questo metodo è sbagliato dato che ritorna sempre null,ma in questi casi (e come sai non è la prima volta che capita),come si affronta il problema?

    Grazie!

  5. #15
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da onepiece007
    Però penso che nella tua,sarebbe più facile fare il thread-safe,anche perchè hai garantito l'invariant.Forse a causa di boolean che semplifica le cose?
    No. Per garantire quell'invariant è necessaria una sequenza di operazioni che viene definita in generale "check-then-act" ovvero controlla qualcosa e poi fai qualcosa. Nel nostro caso specifico: controlla che non ci sia il nome e poi aggiungi l'elemento se non c'è.
    In ambito concorrente, una tale sequenza di operazioni va fatta "atomicamente", cioè in modo non divisibile.
    Senza una opportuna sincronizzazione, tecnicamente è possibile che con una tempistica molto "sfortunata" due thread che vogliono aggiungere uno stesso nome, "vedano" entrambi che il nome non è presente ed entrambi lo aggiungano in rubrica! Questa è quella che si chiama "race condition".

    Originariamente inviato da onepiece007
    Comunque stamane prima di leggere la tua risposta,ho modificato gli altri metodi.Ma a differenza di aggiungi(),CREDO e dico CREDO di aver garantito a mio modo l'invariant.
    Eliminare un elemento non mi sembra che vada a toccare l'invariant relativo ai nomi non duplicati.
    Semmai anche lì c'è un "check-then-act": controllo che il nome sia quello che voglio, quindi elimino l'elemento.

    Originariamente inviato da onepiece007
    Voglio comunque avvisarti,che il nostro corso riguarda la programmazione,quind java è nettamente secondario.Per questo non conosciamo alcuni concetti,terminologie,tecniche raffinate di "java".
    Ok ok


    Originariamente inviato da onepiece007
    Approfitto dell'occasione per chiarire un altro mio dubbio.
    Devo riscrivere l'ultimo metodo che consiste nell'ordinare in ordine alfabetico l'elenco.Ma questo non è un problema dato che l'algoritmo è corretto.Il problema è elminare il System.out.println.
    Io ho fatto cosi:
    codice:
    //Metodo che stampa tutte le info di tutti gli elementi della lista (vincolo:in ordine alfabetico)
    public String informazioni(){
    	int i = 0;
    	int j = 0;
    	int k = 0;
    	Persona contatto = contatti.get(i);
    	for (i = 0;i < contatti.size()-1;i++){
    		for (j=0;j<contatti.size()-i-1;j++){
    		if ( contatti.get(j).getNome().compareTo(contatti.get(j+1).getNome()) > 0 ){
    			contatto = contatti.get(j);
    			contatti.set(j, contatti.get(j+1));
    			contatti.set(j+1, contatto);		
    			}
    		}
    	}
    	for (k=0;k < contatti.size();k++){
    		return contatti.get(k).getInfo();
    	}
    	return null;
    }
    Sono cosciente del fatto che questo metodo è sbagliato dato che ritorna sempre null,ma in questi casi (e come sai non è la prima volta che capita),come si affronta il problema?
    Non ho ben capito perché hai fatto all'inizio un
    Persona contatto = contatti.get(i);

    che non dovrebbe affatto servire.

    Comunque l'ordinamento sarebbe più logico farlo come metodo separato. L'obiettivo di informazioni() dovrebbe essere quello di fornire una "stringona" che contiene le informazioni su tutti gli elementi. Per darti una idea del concetto:

    codice:
    ArrayList<String> arr = new ArrayList<String> ();
    arr.add ("ciao");
    arr.add ("prova");
    
    String s = arr.toString();
    
    System.out.println (s);
    stampa in output:

    [ciao, prova]

    In pratica l'array list fa una iterazione sugli elementi e su ognuno invoca il toString() accodando poi tutto in una unica stringa. Puoi farlo usando l'operatore + ma sarebbe poco efficiente. In questi casi si usa StringBuffer o meglio StringBuilder.

    Per ottenere una stringa come quella sopra, si può fare in modo generale così:

    codice:
    StringBuilder sb = new StringBuilder ();
    sb.append ("[");
    
    boolean first = true;
    
    for (Object o : arr)
    {
        if (!first)
            sb.append (", ");
        sb.append (o.toString ());
        first = false;
    }
    
    sb.append ("]");
    
    String str = sb.toString();
    Ma il formato lo puoi/devi decidere anche tu.
    Andrea, Senior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  6. #16
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    42
    Il problema è che non possiamo usare la classe StringBuilder,dato che non la conosciamo.
    La traccia vuole che quel metodo,stampi a video tutte le info di tutti i contatti.
    Ma la traccia vuole anche che devo scrivere su un file di testo,tutti i contatti con le relative info.
    Allora "furbamente" sfrutto quel metodo sia per stampare a video,che stampare su un file di testo.
    Per questo motivo,devo assolutamente far ritornare a quel metodo una stringona(in realtà più stringone),che verranno visualizzate in esecuzione e sul file di testo!

    Non riesco a capire come far ritornare innocentemente una stringa...

  7. #17
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da onepiece007
    Il problema è che non possiamo usare la classe StringBuilder,dato che non la conosciamo.
    Ok, allora usa l'operatore di concatenazione delle stringhe (+).

    codice:
    String out = "";
    
    for (Persona persona : contatti)
        out += persona.getNome() + ";";
    È molto inefficiente ma se non puoi fare altro ..... credo che per te vada bene. Qui sopra ho fatto concatenare tutti i nomi, terminati ognuno da un ';'. Tu ovviamente cambia pure il formato o aggiungi altri dati come ti pare.
    Andrea, Senior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  8. #18
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    42
    Si ho provato a fare cosi:
    codice:
    	//Metodo che "ritorna" tutte le info di tutti i contatti
    	public String stampa(){
    		String out = "";
    		for (Persona contatto : contatti)
    		   out += contatto.getNome() + ";";
    	}
    Ma anche se faccio il return è intrappolato all'interno del ciclo.
    Ora non so se return effettivamente può essere eseguito più volte in un metodo,dato che return ha il compito di terminare il metodo.
    L'obiettivo è quello di fare ritornare tutte le stringhe contententi tutte le info dei contatti.

    Ho provato anche con Persona ma ho lo stesso problema a causa del ciclo for!


  9. #19
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da onepiece007
    Ma anche se faccio il return è intrappolato all'interno del ciclo.
    Ora non so se return effettivamente può essere eseguito più volte in un metodo,dato che return ha il compito di terminare il metodo.
    Devi fare il return out; chiaramente dopo il for, non dentro il for!!
    Andrea, Senior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  10. #20
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    42
    Originariamente inviato da andbin
    Devi fare il return out; chiaramente dopo il for, non dentro il for!!
    Perfetto funziona tutto alla grande,ma ci sta l'ultimo "ma" da risolvere,cioè la formattazione testo!
    Allora,abbiamo il metodo:
    codice:
    public String stampa(){
    		String out = "";
    		for (Persona contatto : contatti){
    		   out += contatto.getInfo() + " ; ";
    		}
    		return out;
    	}
    Il file di test:
    codice:
    PrintWriter scrittore = new PrintWriter("/home/lord/Desktop/prova.txt");
    	Rubrica rub = new Rubrica();
    	rub.aggiungi("ciccio", "12312", "21983");
    	rub.aggiungi("pluto", "1231231", "232");
    	scrittore.println(rub.stampa());
    	scrittore.close();
    E l'output che purtroppo sta tutto su una stringa!
    Nome:ciccio Telefono:12312 Fax:21983 ; Nomeluto Telefono:1231231 Fax:232 ;
    Sarebbe difficile avere 100 contatti da leggere tutti su una stringa!
    Ci sta un modo per fare un ritorno a capo?Ho provato ad inserire una stringa vuota nel ciclo ma non va!

    Dovrebbe essere la fine della lunga odissea.... :rollo:

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