Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando
Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando
Abbiamo giocato a lungo a Battlefield 6, abbiamo provato tutte le modalità multiplayer, Redsec, e le numerose personalizzazioni. In sintesi, ci siamo concentrati su ogni aspetto del titolo per comprendere al meglio uno degli FPS più ambiziosi della storia dei videogiochi e, dopo quasi due mesi, abbiamo tirato le somme. In questo articolo, condividiamo con voi tutto ciò che è Battlefield 6, un gioco che, a nostro avviso, rappresenta esattamente ciò che questo genere attendeva da tempo
Antigravity A1: drone futuristico per riprese a 360° in 8K con qualche lacuna da colmare
Antigravity A1: drone futuristico per riprese a 360° in 8K con qualche lacuna da colmare
Abbiamo messo alla prova il drone Antigravity A1 capace di riprese in 8K a 360° che permette un reframe in post-produzione ad eliche ferme. Il concetto è molto valido, permette al pilota di concentrarsi sul volo e le manovre in tutta sicurezza e decidere con tutta tranquillità come gestire le riprese. La qualità dei video, tuttavia, ha bisogno di uno step in più per essere competitiva
Sony Alpha 7 V, anteprima e novità della nuova 30fps, che tende la mano anche ai creator
Sony Alpha 7 V, anteprima e novità della nuova 30fps, che tende la mano anche ai creator
Dopo oltre 4 anni si rinnova la serie Sony Alpha 7 con la quinta generazione, che porta in dote veramente tante novità a partire dai 30fps e dal nuovo sensore partially stacked da 33Mpixel. L'abbiamo provata per un breve periodo, ecco come è andata dopo averla messa alle strette.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 17-06-2009, 18:36   #1
InsomNia_Italy
Member
 
Iscritto dal: Jan 2007
Messaggi: 75
[JAVA] Alcune perplessità riguardo le classi...

Ciao a tutti.

Sto facendo un po di pratica nella programmazione Java ed un po alla volta sto riuscendo e capendo il funzionamento del tutto. Portate pazienza se non sarò tecnico

Questo pomeriggio stavo provando a creare un programmino semplice semplice per l'immissione in array di oggetti di Classi scolastiche e relativi Alunni di ogni classe. Ho creato due classi, proprio ALUNNO e CLASSESCUOLA. Pubblico qui il codice completo:

Codice:
import java.io.*;
import java.util.*;

public class Scuola{
	static int sizeClassiScuola = 0;
	private static CLASSESCUOLA [] classescuola = new CLASSESCUOLA[50];
	static BufferedReader in = new BufferedReader( new InputStreamReader( System.in ) );
	
        public static void main(String args[]) throws IOException{		
    		//-------------------------------------------------------
	 for(;;){  	
     			System.out.println("-----------------------------------------------");
     			System.out.println("Rubrica elettronica Scuola");
		        System.out.println();
		        System.out.println("1) Visualizza classi e alunni");
		        System.out.println("2) Aggiungi nuova classe");
		        System.out.println("0) Chiudere rubrica");
		        System.out.println();
		    //-------------------------------------------------------
	    		int Scelta = 0;
	 ciclo: for(;;){
		        System.out.print("Inserire il numero della tua scelta: ");
			Scelta = Integer.parseInt(in.readLine());      
			switch(Scelta){
		        case 1: 
		        	if (sizeClassiScuola>0){
		        		//VISUALIZZARE CONTATTI
		        		Scuola.VisualizzaClassi();
		            	in.readLine();
		        	}else{ 
		        		System.out.println("Nessuna classe da visualizzare!");
		        		in.readLine();
		        	}
		        	break ciclo;
		        case 2:
		        	//AGGIUNGI NUOVA CLASSE
		        	Scuola.AggiungiClasse();
		        	break ciclo;
		        case 0:
		        	//CHIUDERE RUBRICA
		        	System.out.println("Chiusura agenda...");		        	
		        	System.exit(0);
		        default:
		        	//SCELTA NON VALIDA
		        	System.out.println("Scelta non valida");		           
			 }
		 }}
        }
               
        public static void AggiungiClasse() throws IOException{
        	int quanteClassi = 0;
        	String nuovonome = "";
        	String linea = "";
        	System.out.print("Quante classi vuoi aggiungere?: ");
        	quanteClassi = Integer.parseInt(in.readLine());
        	System.out.println("-----------------------------------------------");
        	System.out.println("I dati vanno inseriti nella forma: ( IA - IIB - IIIC - IVD - VE)");
        	//CICLO DI ACQUISIZIONE
        	int sizePreAcquisizione = sizeClassiScuola;
        	for (int contClasse=0;contClasse<quanteClassi;contClasse++){
        		System.out.print("Classe " + (contClasse+1) + " su "+ quanteClassi + ":");
        		nuovonome = in.readLine();
        		System.out.print("Quanti alunni vuoi aggiungere nella " + nuovonome + "?: ");
            	int QuantiAlunni = Integer.parseInt(in.readLine());
        		classescuola[contClasse+sizePreAcquisizione] = new CLASSESCUOLA(nuovonome,QuantiAlunni);
        		sizeClassiScuola++;
            	System.out.println("-----------------------------------------------");
            	System.out.println("I dati vanno inseriti nella forma: COGNOME NOME");
            	//CICLO DI ACQUISIZIONE
            			for (int contAlunni=0;contAlunni<QuantiAlunni;contAlunni++){
            				System.out.print("Nominativo " + (contAlunni+1) + " su "+ QuantiAlunni + ":");
            				linea = in.readLine();
            				//SPEZZO LA STRINGA
            				StringTokenizer tz = new StringTokenizer(linea);
            				String cognome = tz.nextToken();
            				String nome = tz.nextToken();
            				classescuola[contClasse].newAlunno(cognome, nome, contAlunni);
            			}
        	}
        }
        
        public static void VisualizzaClassi() throws IOException{
       		for (int cont=0;cont<sizeClassiScuola;cont++){
        		System.out.println(cont+1 + "° Classe: " + classescuola[cont].getClasse());
        		System.out.println("\t Alunni che compongono la classe:");
        		for (int cont2=0;cont2<classescuola[cont].getNumeroAlunni();cont2++){
        			System.out.println("\t   - " + classescuola[cont].getAlunno(cont2).getCognome() + " " + classescuola[cont].getAlunno(cont2).getNome());
        		}
        	}       
        }
        
} //FINE CLASSE RUBRICA


class ALUNNO{
	private String cognome;
	private String nome;
	
	public ALUNNO(String cogn,String nom)	{
	   cognome = cogn;
	   nome = nom;
	}
	public String getCognome(){
		return cognome;
	}
	public String getNome(){
		return nome;
	}
} //FINE CLASSE ALUNNO
class CLASSESCUOLA{
	private ALUNNO [] al = new ALUNNO[50];
	private String classe;
	private Integer numeroAlunni;
	
	public CLASSESCUOLA(String cl,Integer numAlunni)	{
	   classe = cl;
	   numeroAlunni = numAlunni;
	}
	public String getClasse(){
		return classe;
	}	
	public Integer getNumeroAlunni(){
		return numeroAlunni;
	}	
	public ALUNNO getAlunno(Integer Indice){
		return al[Indice];
	}
	public String newAlunno(String Cognome,String Nome,Integer Cont){
		al[Cont] = new ALUNNO(Cognome,Nome);
		return null;
	}
	
} //FINE CLASSE CLASSESCUOLA
Il programma in se funziona ma ho alcune perplessità. E' necessario implementare all'interno della classe CLASSESCUOLA il codice:
Codice:
	public String newAlunno(String Cognome,String Nome,Integer Cont){
		al[Cont] = new ALUNNO(Cognome,Nome);
		return null;
	}
per poter aggiungere un nuovo alunno all'interno della classe?
Devo necessariamente specificare l'indice di ogni nuovo alunno creato?
Non esiste un modo più semplice per aggiungere un nuovo alunno in coda a quelli precedentemente creati, qualora ce ne fossero?

Altra cosa.

Devo necessariamente specificare ogni volta il numero di oggetti da creare?
Codice:
	private ALUNNO [] al = new ALUNNO[50];
Come posso rendere il tutto automatico per evitare errori di NullPointetc...?

Ultima domanda
All'interno del metodo VisualizzaClassi utilizzo
Codice:
classescuola[cont].getAlunno(cont2).getCognome()
Va bene cosi oppure mi conviene dichiarare l'oggetto ALUNNO di tipo public ed utilizzare direttamente
Codice:
classescuola[cont].al[cont2].getCognome()
senza utlizzare il metodo getAlunno della classe CLASSESCUOLA?

Grazie, spero possiate aiutarmi
InsomNia_Italy è offline   Rispondi citando il messaggio o parte di esso
Old 17-06-2009, 18:57   #2
carter100
Senior Member
 
Iscritto dal: Jul 2007
Messaggi: 1159
Premetto che tutto il codice non l'ho visto, è una enormità.
Per il primo dubbio, sull'indice e sugli elementi del vettore, se usi la classe ArrayList hai una allocazione dinamica, è semplice da usare.

Per l'ultimo dubbio, non ho tempo ora di dare 1 sguardo al codice, in ogni caso se usi un arraylist avrai il metodo get per recuperare l'alunno all'indice i, quindi quel rigo un pò andrà modificato uguale
carter100 è offline   Rispondi citando il messaggio o parte di esso
Old 17-06-2009, 20:42   #3
morskott
Member
 
Iscritto dal: Jul 2005
Messaggi: 291
Non ho ancora visto il codice, ma se invece di avere un array che ti devi gestire indici e a creazione a dimensione prefissata immutabile usi invece un oggetto "List"? per inserire basta chiamare il metodo "add", per accedere il metodo "get" che prende come parametro l'indice al quale vuoi accedere e se poi ci saà un posto dove devi per forza usare un array ci puoi invocare il metodo "toArray" che ti restituisce un array del contenuto.

Poi io non lascerei vedere all'esterno gli indici, ho intravisto un
Codice:
public String newAlunno(String Cognome,String Nome,Integer Cont){
		al[Cont] = new ALUNNO(Cognome,Nome);
		return null;
	}
che impone al chiamante la conoscenza della struttura dati interna su cui agisci, permettendogli per esempio di generarti un IndexOutOfRangeException in caso ti metta un indice superiore al massimo consentito o peggio ancora di sovrascriverti oggetti già presenti, al massimo se devi proprio utilizzare un array dentro alla classe di definizione farei
Codice:
public class XXX{

//altro
private Alunno[] alunni;
private int indiceAlunni;

public XXX(){
this.alunni=new Alunni[size];
this.indiceAlunni=0;
}

public void addAlunno(String nome,String cognome){
this.alunni[this.indiceAlunni]=new Alunno(nome,cognome);
this.indiceAlunni++;
}
}
Se invece usi un oggetto List
Codice:
public class XXX{

private List<Alunno> listaAlunni;

public XXX(){
this.listaAlunni=new ArrayList<Alunno>(); //oppure anche new LinkedList<Alunno>()
}

public void addAlunno(String nome,String cognome){
this.listaAlunni.add(new Alunno(nome,cognome));
}
}
.

Mo leggiucchio il codice.
__________________
CPU: Intel Core 2 Quad Q6600 - Mobo: Asus P5E - RAM:4x2GB DDR2 - sk video: Power Color ATI Radeon HD3870 - HD:Western Digital 750GB
morskott è offline   Rispondi citando il messaggio o parte di esso
Old 17-06-2009, 21:22   #4
morskott
Member
 
Iscritto dal: Jul 2005
Messaggi: 291
Ho visionato il codice, mi sembra un po di non facilissima comprensione e facile da malintendere, ne ho fatta una mia versione del tuo programma, vedi se ti puo dare qualche hint
Codice:
import java.util.*;

public class MainScuola{
	private Scuola scuola;
	
	private static final String VIS="1";
	private static final String INS="2";
	private static final String EXIT="3";
	
	public MainScuola(String nomeScuola){
		this.scuola=new Scuola(nomeScuola);
	}
	
	public void visualizzaScuola(){
		System.out.println("Visualizzando la scuola:"+this.scuola.getNome());
		Set<Classe> leClassi=this.scuola.getClassi();
		for (Classe classe:leClassi){
			System.out.println("Visualizzando la classe:"+classe.getNome());
			Set<Alunno> gliAlunni=classe.getAlunni();
			for (Alunno alunno:gliAlunni){
				System.out.println("Visualizzando l'alunno:"+alunno.getNome()+" "+alunno.getCognome());
			}
		}
	}
	
	public void aggiungiClasse(){
		Scanner scanner=new Scanner(System.in);
		System.out.print("Inserisci il nome della classe:");
		Classe classe=new Classe(scanner.nextLine());
		System.out.println("Inserire alunni (q per terminare)");
		while (true){ //soluzione "sporca" ma in 3 sec mi viene in mente questa
			System.out.print("Nome alunno\n>>");
			String nomeAlunno=scanner.nextLine();
			if (nomeAlunno.equals("q")) break;
			System.out.print("Cognome alunno\n>>");
			String cognomeAlunno=scanner.nextLine();
			if (cognomeAlunno.equals("q")) break;
			Alunno alunno=new Alunno(nomeAlunno,cognomeAlunno);
			classe.addAlunno(alunno);
		}
		this.scuola.addClasse(classe);
	}
	
	public void run(){
		System.out.println("Benvenuti alla rubrica elettronica della scuola "+this.scuola.getNome());
		boolean continua=true;
		Scanner scanner=new Scanner(System.in);
		while (continua){
			System.out.print(VIS+") per visualizzare la scuola\n"+INS+") per inserire classi\n"+EXIT+") per uscire\n>>");
			String input=scanner.nextLine();
			if (input.equals(VIS)){
				this.visualizzaScuola();
			}
			if (input.equals(INS)){
				this.aggiungiClasse();
			}
			if (input.equals(EXIT)){
				continua=false;
			}
		}
	}
	
	public static void main(String[] args){
		MainScuola main=new MainScuola("Montessori");
		main.run();
	}
}

class Scuola{
	private String nome;
	private Set<Classe> leClassi;
	
	public Scuola(String nome){
		this.nome=nome;
		this.leClassi=new HashSet<Classe>();
	}
	
	public String getNome(){
		return this.nome;
	}
	
	public void addClasse(Classe c){
		this.leClassi.add(c);
	}
	
	public Set<Classe> getClassi(){
		Set<Classe> ris=new HashSet<Classe>();
		ris.addAll(this.leClassi);
		return ris;
	}
}

class Classe{
	private String nome;
	private Set<Alunno> gliAlunni;
	
	public Classe(String nome){
		this.nome=nome;
		this.gliAlunni=new HashSet<Alunno>();
	}
	
	public String getNome(){
		return this.nome;
	}
	
	public void addAlunno(Alunno al){
		this.gliAlunni.add(al);
	}
	
	public Set<Alunno> getAlunni(){
		Set<Alunno> ris=new HashSet<Alunno>();
		ris.addAll(this.gliAlunni);
		return ris;
	}
}

class Alunno{
	private String nome;
	private String cognome;
	
	public Alunno(String nome,String cognome){
		this.nome=nome;
		this.cognome=cognome;
	}
	
	public String getNome(){
		return this.nome;
	}
	
	public String getCognome(){
		return this.cognome;
	}
}
__________________
CPU: Intel Core 2 Quad Q6600 - Mobo: Asus P5E - RAM:4x2GB DDR2 - sk video: Power Color ATI Radeon HD3870 - HD:Western Digital 750GB
morskott è offline   Rispondi citando il messaggio o parte di esso
Old 17-06-2009, 22:50   #5
InsomNia_Italy
Member
 
Iscritto dal: Jan 2007
Messaggi: 75
Mamma mia, ti ringrazio moltissimo!

Domani me lo studio per bene, in caso di dubbi chiederò

Grazie ancora!! E' decisamente più pulito il tuo codice
InsomNia_Italy è offline   Rispondi citando il messaggio o parte di esso
Old 18-06-2009, 00:18   #6
morskott
Member
 
Iscritto dal: Jul 2005
Messaggi: 291
In questo modo le informazioni son tutte su ram, quindi quando chiudi il programma perdi tutti i dati, se vuoi renderli permanenti li puoi mettere su files, il modo più semplice è usando un oggetto ObjectOutputStream per scrivere su file e ObjectInputStream per leggerci, ma andrebbero fatte lievissime modifiche al codice, la javadoc ti sarà utilissima!!!

Poi ricorda che è tutto un fatto di "responsabilità", cioè i metodi devon sapere il minimo indispensabile sul resto dell'implementazione, se vedi per aggiungere un Alunno ad una Classe si invoca il metodo"addAlunno" senza nemmeno sapere cosa succede dietro, perchè la responsabilità di aggiungere un Alunno ce l'ha la Classe, se un domani devo modificare una Classe facendogli registrare un Alunno, per esempio, su una macchina remota o ho altre esigenze devo solo o estendere la Classe facendo overriding del metodo o riscrivere solo e solamente il codice della Classe lasciando le altri parti intonse.

I "getClassi" e "getAlunni" fanno una copia dei Set per far in modo che i chiamanti non possano modificare la mia propria struttura dati, rimuovendomi o aggiungendomi oggetti fuori dal mio controllo (fuori dal controllo della classe "Scuola" o "Classe")
__________________
CPU: Intel Core 2 Quad Q6600 - Mobo: Asus P5E - RAM:4x2GB DDR2 - sk video: Power Color ATI Radeon HD3870 - HD:Western Digital 750GB

Ultima modifica di morskott : 18-06-2009 alle 00:26.
morskott è offline   Rispondi citando il messaggio o parte di esso
Old 18-06-2009, 09:57   #7
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Quote:
Originariamente inviato da morskott Guarda i messaggi
I "getClassi" e "getAlunni" fanno una copia dei Set per far in modo che i chiamanti non possano modificare la mia propria struttura dati, rimuovendomi o aggiungendomi oggetti fuori dal mio controllo (fuori dal controllo della classe "Scuola" o "Classe")
Se dei dati tornati da quei due metodi si vogliono rendere possibili solo operazioni di lettura, un'alternativa potrebbe essere quella di ritornare una versione "immodificabile" (unmodifiable) della collezione stessa (in questo caso un Set) per esempio così:
Codice:
...
public Set<Alunno> getAlunni(){
	return Collections.unmodifiableSet(this.gliAlunni);
}
In questo modo non si consente al chiamate di modificare in alcun modo il Set (se tenta di farlo direttamente o tramite iteratore viene sollevata un'eccezione di tipo UnsupportedOperationException) ma solo di leggerlo.
Il leggero vantaggio in termini prestazionali è dato dal fatto che il Set non viene duplicato ad ogni chiamata.
La classe di utilità "Collections" si trova sempre nel package java.util.

Per chi è più curioso e vuole un'idea di come siano implementate versioni immodificabili delle collezioni, posto questo link.
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)

Ultima modifica di banryu79 : 18-06-2009 alle 10:16.
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 18-06-2009, 15:12   #8
InsomNia_Italy
Member
 
Iscritto dal: Jan 2007
Messaggi: 75
Quote:
Originariamente inviato da morskott Guarda i messaggi
In questo modo le informazioni son tutte su ram, quindi quando chiudi il programma perdi tutti i dati, se vuoi renderli permanenti li puoi mettere su files, il modo più semplice è usando un oggetto ObjectOutputStream per scrivere su file e ObjectInputStream per leggerci, ma andrebbero fatte lievissime modifiche al codice, la javadoc ti sarà utilissima!!
Si la gestione dei files (lettura / scrittura) l'ho testata l'altro giorno. Non è affatto difficile...almeno per quello che ho dovuto farci io
InsomNia_Italy è offline   Rispondi citando il messaggio o parte di esso
Old 18-06-2009, 15:27   #9
morskott
Member
 
Iscritto dal: Jul 2005
Messaggi: 291
Puoi scrivere su files interi oggetti, senza fare scritture campo per campo, basta che implementi per la classe che vuoi salvare l'interfaccia Serializable e che tutti gli oggetti d'istanza facciano lo stesso.
__________________
CPU: Intel Core 2 Quad Q6600 - Mobo: Asus P5E - RAM:4x2GB DDR2 - sk video: Power Color ATI Radeon HD3870 - HD:Western Digital 750GB
morskott è offline   Rispondi citando il messaggio o parte di esso
Old 18-06-2009, 15:32   #10
InsomNia_Italy
Member
 
Iscritto dal: Jan 2007
Messaggi: 75
Ok, avrei qualche domandina per chiarirmi le idee:

Codice:
class Classe{
	private String nome;
	private Set<Alunno> gliAlunni;
	
	public Classe(String nome){
		this.nome=nome;
		this.gliAlunni=new HashSet<Alunno>();
	}
	
	public String getNome(){
		return this.nome;
	}
	
	public void addAlunno(Alunno al){
		this.gliAlunni.add(al);
	}
	
	public Set<Alunno> getAlunni(){
		Set<Alunno> ris=new HashSet<Alunno>();
		ris.addAll(this.gliAlunni);
		return ris;
	}
}
Qui ad esempio utilizzi private Set<Alunno> gliAlunni.
Corrisponde a private Alunno[] gliAlunni che crea gliAlunni di tipo Alunno[]?
Bisogna utilizzare Set perchè stai utilizzando poco dopo HashSet che corrisponde più o meno a:
ALUNNO gliAlunni= new ALUNNO[16] oppure no? Solo che utilizzando HashSet non avrai bisogno non dovrai preoccuparti del limite di numero degli oggetti creati no?

Ultima cosa, nel metodo aggiungiClasse verso la fine fai:
Codice:
			Alunno alunno=new Alunno(nomeAlunno,cognomeAlunno);
			classe.addAlunno(alunno);
Come fa a sapere in quale oggetto classe deve creare i nuovi alunni se non specifichi nessun indice? Li inserisce nell'ultimo oggetto classe creato?

Grazie per l'aiuto
InsomNia_Italy è offline   Rispondi citando il messaggio o parte di esso
Old 18-06-2009, 16:39   #11
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Quote:
Originariamente inviato da InsomNia_Italy Guarda i messaggi
Qui ad esempio utilizzi private Set<Alunno> gliAlunni.
Corrisponde a private Alunno[] gliAlunni che crea gliAlunni di tipo Alunno[]?
Come concetto, se ho capito ciò che intendi, diciamo di sì, nel senso che dichiara un insieme di oggetti di tipo Alunno, così come
Codice:
private Alunno[] gliAlunni;
dichiara un array (che possiamo considerare un insieme) di oggetti di tipo Alunno.

Tecnicamente sono due cose molto differenti.
Uno è un array di oggetti di tipo Alunno.
L'altro è una collezione, più precisamente un Set, di oggetti di tipo Alunno.

Le collezioni (Collection Framework) le trovi nel JDK della Sun, nel package java.util.
Gli array sono compresi nel linguaggio invece

Se usi un array è tua la responsabilità di dimensionarlo, gestirlo, stare atento agli indici e vattelapesca vari.

Quando usi una collezione del JDK, hai invece per le mani un oggetto e quindi operi con i metodi che quell'oggetto ti mette a disposizione. Esistono vari tipi di "contenitori", ognuno dei quali ha delle caratteristiche ben precise e viene usato in preferenza agli altri a seconda dello scopo specifico.


Quote:
Originariamente inviato da InsomNia_Italy Guarda i messaggi
Bisogna utilizzare Set perchè stai utilizzando poco dopo HashSet che corrisponde più o meno a:
ALUNNO gliAlunni= new ALUNNO[16] oppure no?
Set è un interfaccia. HashSet è una classe concreta che implementa l'interfaccia Set.
HashSet internamente usa come contenitore dei dati una HashMap, non un array. Il fatto che sia un Set (dato che ne implementa l'interfaccia) significa che ha le caratteristiche di Set. Per esempio una caratteristica di Set è che non ammette elementi duplicati al suo interno. Quindi se provi a inserire due volte lo stesso Alunno, il secondo inserimento verrà ignorato (il metodo add() di Set torna un boolean: vero se l'elemento è stato inserito, falso se non è stato inserito).
Inoltre, a differenza di un array, un Set non è a accesso casuale ai suoi elementi. Ovvero se con un array puoi dire:
Codice:
// supponiamo che 'arrayAlunni' sia un'istanza di tipo Alunno[]
Alunno decimoAlunno = arrayAlunni[9];
e ottenere il decimo Alunno inserito nell'array, perchè l'array mantiene gli elementi indicizzati, con Set non hai questa possibilità di accesso.
A ben guardare, per quello che si può supporre dell'uso che farai degli Alunni nella tua applicazione, probabilmente non avrai mai la neccessità di accedere ad un Alunno specificato in base all'indice di posizione nella collezione.
Sarà più probabile che, dati tutti gli Alunni di una Classe, avrai la neccessità o di scandirli tutti uno a uno, oppure avrai bisogno di un Alunno specifico, ma in quel caso lo identificherai rispetto al suo nome/cognome, non alla posizione nella collezione.

Quote:
Originariamente inviato da InsomNia_Italy Guarda i messaggi
Solo che utilizzando HashSet non avrai bisogno non dovrai preoccuparti del limite di numero degli oggetti creati no?
Esatto. Questo perchè appunto tu passi un Alunno da inserire dentro il Set (HashSet) chiamando il suo metodo 'add' e passandogli come argomento l'elemento (l'Alunno) da inserire, senza preoccuparti di altro.
La gestione interna a HashSet degli elementi (come sono memorizzati, dove, quanti ce ne sono) a te non interessa, e viene svolta dietro le quinte da HashSet stesso (come detto prima, tra l'altro internamente non usa neanche un array per memorizzare gli elementi, ma una HashMap; questo per avere dei vantaggi prestazionali per certe operazioni, ed è uno dei motivi che spingono a scegliere di utilizzare una collezione piuttosto che un'altra).


Quote:
Originariamente inviato da InsomNia_Italy Guarda i messaggi
Ultima cosa, nel metodo aggiungiClasse verso la fine fai:
Codice:
			Alunno alunno=new Alunno(nomeAlunno,cognomeAlunno);
			classe.addAlunno(alunno);
Come fa a sapere in quale oggetto classe deve creare i nuovi alunni se non specifichi nessun indice? Li inserisce nell'ultimo oggetto classe creato?
Parli del metodo 'aggiungiClasse' della classe MainScuola postata da morskott:
Codice:
public void aggiungiClasse(){
		Scanner scanner=new Scanner(System.in);
		System.out.print("Inserisci il nome della classe:");
		Classe classe=new Classe(scanner.nextLine());
		System.out.println("Inserire alunni (q per terminare)");
		while (true){ //soluzione "sporca" ma in 3 sec mi viene in mente questa
			System.out.print("Nome alunno\n>>");
			String nomeAlunno=scanner.nextLine();
			if (nomeAlunno.equals("q")) break;
			System.out.print("Cognome alunno\n>>");
			String cognomeAlunno=scanner.nextLine();
			if (cognomeAlunno.equals("q")) break;
			Alunno alunno=new Alunno(nomeAlunno,cognomeAlunno);
			classe.addAlunno(alunno);
		}
		this.scuola.addClasse(classe);
Se guardi il metodo concentrandoti nell'uso che fa dei due oggetti 'classe' di tipo Classe e 'alunno' di tipo Alunno e tieni presente la definizione della classe Classe:
Codice:
class Classe{
	private String nome;
	private Set<Alunno> gliAlunni;
	
	public Classe(String nome){
		this.nome=nome;
		this.gliAlunni=new HashSet<Alunno>();
	}
	
	public String getNome(){
		return this.nome;
	}
	
	public void addAlunno(Alunno al){
		this.gliAlunni.add(al);
	}
	
	public Set<Alunno> getAlunni(){
		Set<Alunno> ris=new HashSet<Alunno>();
		ris.addAll(this.gliAlunni);
		return ris;
	}
}
vedrai che essa ha un metodo chiamato 'addAlunno' che prende in ingresso un singolo Alunno e lo inserisce nella collezione di tipo Set che dichiara al suo interno, tramite il metodo 'add' di Set (in realtà implementato in HashSet dato che è questa l'implementazione che viene istanziata e usata mediante l'interfaccia Set).
Quindi, come detto prima, è HashSet che al suo interno si preoccupa dei dettagli.
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)

Ultima modifica di banryu79 : 18-06-2009 alle 16:43.
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 18-06-2009, 17:36   #12
morskott
Member
 
Iscritto dal: Jul 2005
Messaggi: 291
Se poi hai proprio necessità di accedere all'i-esimo elemento di Alunno o Classe invece di usare un Set (instanziandolo con un HashSet) puoi usare un List (che si instanzia con un ArrayList o con un LinkedList) e usare il metodo "get(i)" dove i è l'indice che vuoi accedere. Se vuoi invece fare un insieme ordinato userai invece un "SortedSet" (con implementazione TreeSet) a cui o passi oggetti di tipo "Comparable" (in pratica devi far implementare l'interfaccia Comparable agli oggetti che inserisci nell'insieme) o passandogli un oggetto "Comparator", o meglio la tua implementazione. Leggendo la javadoc sotto il package java.util sarà molto più chiaro.

Ricordati che java è case sensitive, nel senso che "classe" è diverso da "Classe", nel mio codice quando ho fatto "classe.addAlunno(alunno)" invocavo sull'oggetto puntato dalla variabile "classe" il metodo "addAlunno", non mi riferivo al nome della classe, che è "Classe".
__________________
CPU: Intel Core 2 Quad Q6600 - Mobo: Asus P5E - RAM:4x2GB DDR2 - sk video: Power Color ATI Radeon HD3870 - HD:Western Digital 750GB

Ultima modifica di morskott : 18-06-2009 alle 17:42.
morskott è offline   Rispondi citando il messaggio o parte di esso
Old 18-06-2009, 19:10   #13
InsomNia_Italy
Member
 
Iscritto dal: Jan 2007
Messaggi: 75
Siete stati precisissimi. Ho capito bene il funzionamento e vi ringrazio.

Ho anche fatto un'altro programmino simile, tanto per vedere se avevo capito il meccanismo e funziona alla grande Invece di avere SCUOLA -> CLASSI -> TOT alunni per classe ho fatto RUBRICA -> NOMINATIVI -> TOT numeri di cellulare per nominativo

Ora mi cimento nell'aggiunta del modifica e del rimuovi. Vediamo come va
InsomNia_Italy è offline   Rispondi citando il messaggio o parte di esso
Old 19-06-2009, 19:22   #14
InsomNia_Italy
Member
 
Iscritto dal: Jan 2007
Messaggi: 75
Mi perdo in un bicchiere d'acqua. Ho problemi anche con il remove dannazzione, eppure mi posiziono correttamente e se provo ad utilizzare il metodo CONTAINS mi dice che l'oggetto che intendo eliminare esiste!

Codice:
	public void RimuoviNominativo(){
		Scanner scanner = new Scanner(System.in);
		System.out.print("Inserire COGNOME NOME del nominativo da rimuovere: ");
		String acquisizione = scanner.nextLine();
		StringTokenizer tk = new StringTokenizer(acquisizione);
		String cognome = tk.nextToken();
		String nome = tk.nextToken();
		Set<NOMINATIVO> nominativo = this.rubricacell.getNominativi();
		for (NOMINATIVO nomattuale:nominativo){
			if (nomattuale.getCognome().equals(cognome) && nomattuale.getNome().equals(nome)) {
			nominativo.remove(nomattuale);
			}
		}
	}
Con la modifica invece nessun problema, sono riuscito a farla.

Ultima modifica di InsomNia_Italy : 19-06-2009 alle 19:34.
InsomNia_Italy è offline   Rispondi citando il messaggio o parte di esso
Old 19-06-2009, 19:38   #15
InsomNia_Italy
Member
 
Iscritto dal: Jan 2007
Messaggi: 75
Come non detto Ho trovato l'errore e sono riuscito a fare anche il rimuovi
InsomNia_Italy è offline   Rispondi citando il messaggio o parte di esso
Old 19-06-2009, 20:03   #16
morskott
Member
 
Iscritto dal: Jul 2005
Messaggi: 291
quà entra in gioco il metodo "equals", se noti la classe Object ha un metodo equals che essendo (la classe Object) la radice di tutte le classi in java è ereditato da tutte le classi che crei, esso (il metodo) dice se un oggetto è o no uguale ad un altro, se non fai overriding di equals l'oggetto sul quale lo invochi ti dice se lui ha lo stesso indirizzo di memoria dell'oggetto che gli passi come parametro. Ipotizzo che la tua classe sia
Codice:
class Nominativo{
private String nome;
private String cognome;
}
Tu vuoi che un "Nominativo" sia uguale ad un altro quando sono uguali il nome ed il cognome, quindi il tuo metodo equals sarà
Codice:
public boolean equals(Object o){
if (o!=null && this.getClass().equals(o.getClass())){ //riga 1
Nominativo n=(Nominativo)o; //riga 2
return this.nome.equals(n.nome) && this.cognome.equals(n.cognome); //riga 3
}else{
return false; //riga 4
}
}
Analizziamo la riga 1, per non esser falso tu imponi che il parametro sia diverso da null (gli passi realmente qualcosa) e che la classe del parametro sia uguale alla tua (così Mela sarà sempre diverso da Pera). Se così non è (gli hai passato null o gli hai passato un oggetto di classe diversa) passi alla riga 4 che torna subito false.
Passando alla riga 2 tu dici a questo punto che il parametro è un Nominativo.
Finalmente alla riga 3 dici che i 2 nominativi sono uguali (l'oggetto di invocazione e il parametro) se e solo se sono uguali il nome E il cognome.

(Adesso forse non lo capirai, ma quando fai overriding di equals sei obbligata a farlo pure di hashCode, e sugli stessi parametri sui quali hai fatto l'equals, ciò si traduce in
Codice:
public int hashCode(){
return this.nome.hashCode()+31*this.cognome.hashCode();
}
)

In questo modo la tua classe diventa
Codice:
class Nominativo{
private String nome;
private String cognome;

public boolean equals(Object o){
if (o!=null && this.getClass().equals(o.getClass())){ //riga 1
Nominativo n=(Nominativo)o; //riga 2
return this.nome.equals(n.nome) && this.cognome.equals(n.cognome); //riga 3
}else{
return false; //riga 4
}
}

public int hashCode(){
return this.nome.hashCode()+31*this.cognome.hashCode();
}
}
Mo ti starai chiedendo perchè ho scritto sta manfrina, semplice, in questo modo il remove diventa
Codice:
public void RimuoviNominativo(){
		Scanner scanner = new Scanner(System.in);
		System.out.print("Inserire COGNOME NOME del nominativo da rimuovere: ");
		String acquisizione = scanner.nextLine();
		StringTokenizer tk = new StringTokenizer(acquisizione);
		String cognome = tk.nextToken();
		String nome = tk.nextToken();
		Set<NOMINATIVO> nominativo = this.rubricacell.getNominativi();
		nominativo.remove(new Nominativo(nome,cognome));
	}
Un altro modo per farlo senza fare overriding sarebbe
Codice:
public void RimuoviNominativo(){
		Scanner scanner = new Scanner(System.in);
		System.out.print("Inserire COGNOME NOME del nominativo da rimuovere: ");
		String acquisizione = scanner.nextLine();
		StringTokenizer tk = new StringTokenizer(acquisizione);
		String cognome = tk.nextToken();
		String nome = tk.nextToken();
		Set<NOMINATIVO> nominativo = this.rubricacell.getNominativi();
                NOMINATIVO toDel=null;
		for (NOMINATIVO nomattuale:nominativo){
			if (nomattuale.getCognome().equals(cognome) && nomattuale.getNome().equals(nome)) {
			toDel=nomattuale;
			}
		}
                nominativo.remove(toDel);
	}
PS: I nomi delle classi in java per convenzione seguono il Camel Case, cioè iniziali maiuscole ed il resto minuscolo, cioè Alunno, PrimaClasse, TestTerzaClasse etc etc, essendo solo una convenzione non sei obbligato a seguirla, solo caldamente consigliato
__________________
CPU: Intel Core 2 Quad Q6600 - Mobo: Asus P5E - RAM:4x2GB DDR2 - sk video: Power Color ATI Radeon HD3870 - HD:Western Digital 750GB

Ultima modifica di morskott : 19-06-2009 alle 23:14.
morskott è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando Due mesi di Battlefield 6: dalla campagna al bat...
Antigravity A1: drone futuristico per riprese a 360° in 8K con qualche lacuna da colmare Antigravity A1: drone futuristico per riprese a ...
Sony Alpha 7 V, anteprima e novità della nuova 30fps, che tende la mano anche ai creator Sony Alpha 7 V, anteprima e novità della ...
realme GT 8 Pro Dream Edition: prestazioni da flagship e anima racing da F1 realme GT 8 Pro Dream Edition: prestazioni da fl...
OVHcloud Summit 2025: le novità del cloud europeo tra sovranità, IA e quantum OVHcloud Summit 2025: le novità del cloud...
SpaceX: capitalizzazione di 800 miliardi...
'L'UE dovrebbe essere abolita': la spara...
Non solo smartphone: Samsung sta lavoran...
Nessuno vuole comprare iPhone Air: il va...
Porsche Taycan 2027 elettrica con cambio...
Roscosmos: stazione spaziale russa ROS a...
Auto 2035, sei governi UE (c'è l'...
Chernobyl: la cupola di contenimento non...
SSD come CPU: queste memorie sono in gra...
La previsione di CATL: barche elettriche...
Stangata in arrivo: PC e notebook coster...
Lian Li si è inventata il primo a...
Amazon in raptus sconti: ogni 24 ore nov...
44 idee regalo sotto i 50€: con le offer...
Super Sconti Amazon Haul: ribassi fino a...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 01:56.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v