|
Programmazione 2
-
forum
Messaggi del Thread
|
Autore |
Messaggio |
davide.mottin
|
Thread
Postato:
21 aprile 2005
Titolo:
Ancora Iterator
|
|
|
Arrivato ad un certo punto dell'implementazione della Pila che implementa Collection, ho dovuto, mio malgrado, scontrarmi con il metodo "public Iterator iterator()" (tra l'altro ho visto che sull'altro thread ne parlavano ma ho preferito aprirne uno di nuovo perchè specifico), dopo innumerevoli tenativi e riflessioni non sono riuscito a trovare un metodo scientifico per implementarlo, in quanto : 1. Essendo Iterator un'interfaccia a sua volta non posso istanziarlo 2. Provando a farmi restituire il contenuto della mia pila (come pensavo di aver capito) con un'istruzione del tipo "return contenuto" JDeveloper mi segnava errore 3. Provando a creare un oggetto di tipo Iterator e fare una cosa del tipo Iterator i = new Pila() (che tra l'altro lo reputo sbagliato perchè così creo una nuova Pila e non utilizzo quella che mi passerà l'utente) non funzionava lo stesso...
Come posso fare? Come posso implementare questo bel metodo? Ma anche a cosa serve?
Ringrazio tutti coloro che saranno così gentili da sciogliere i miei dubbi
|
|
|
stefano.chirico
|
Postato:
21 aprile 2005
Titolo:
Re: Ancora Iterator
|
|
|
In generale un iteratore è un oggetto che può essere utilizzato per recuperare tutti gli elementi di una collezione uno per uno. In pratica permette, attraverso un ciclo while, di scorrere tutta la collezione. L'interfaccia Collection contempla il metodo iterator() per fare in modo che qualsiasi classe implementi questa interfaccia fosse in grado di restituire un iteratore alla collezione. Questo iteratore, naturalmente, dovrà "navigare" gli elementi della collezione in maniera coerente con il tipo di collezione. Nel nostro caso, ad esempio, si dovrà scorrere la collezione in modo che il primo elemento raggiunto dall'iteratore sia l'ultimo inserito nella pila (Stack), rispettando così la tecnologia LIFO.
Andando a guardare la documentazione ufficiale di Sun, scopriamo che l'interfaccia Iterator prevede l'implementazione di tre metodi: - boolean hasNext() che restituisce true se l'iteratore ha ancora elementi da navigare - Object next() che restituisce il prossimo elemento dell'iteratore - void remove() che rimuove l'elemento richiamato da next() dalla collezione. Visto che questo metodo è facoltativo, io per ora penserei ad implementare solo i primi due eheheheh.
La nostra pila, attraverso il metodo iterator(), istanzia un nuovo oggetto "di tipo Iterator". Questo significa che istanzia un oggetto la cui classe implementa l'interfaccia Iterator. Quello che dobbiamo fare noi, quindi, è creare una classe che implementi l'interfaccia Iterator i cui metodi hasNext() e next() vadano ad agire sui membri interni del nostro Stack in modo da reagire secondo filosofia LIFO. Per fare questo si può agire in due modi. Il primo, sbagliato perchè mina uno dei fondamenti della programmazione orientata agli oggetti (l'incapsulamento), prevede di avere i membri della classe Stack pubblici (o con visibilità di default), in modo che una classe esterna (o appartenete allo stesso package) possa accedervi. Il secondo è quello di creare la classe che implementa l'interfaccia Iterator all'interno della classe Stack (come se fosse un membro della classe stessa). In questo modo, facendo in pratica parte della classe Stack, è possibile accedere anche ai membri privati di quest'ultima.
Spero di essere stato abbastanza chiaro :) Ciao.
|
|
|
davide.mottin
|
Postato:
21 aprile 2005
Titolo:
Re: Ancora Iterator
|
|
|
La soluzione che, ammetto di non aver pensato , è ottima, quindi se non ho capito male: a. Mi creo una bella classe private interna alla classe Pila del tipo, IteratorPila b. implemento l'interfaccia Iterator in questa classe c. Reimplemento tutti i suoi metodi (o almeno 2) d. All'inerno della funzione iterator() faccio restituire un'istanza della classe appena creata (non visibile all'utente finale) in modo tale che anche l'utente in qualche modo possa avere il suo bell'iteratore!!!...
Right?
|
|
|
stefano.chirico
|
Postato:
21 aprile 2005
Titolo:
Re: Re: Ancora Iterator
|
|
|
davide.mottin wrote: | La soluzione che, ammetto di non aver pensato , è ottima, quindi se non ho capito male: a. Mi creo una bella classe private interna alla classe Pila del tipo, IteratorPila b. implemento l'interfaccia Iterator in questa classe c. Reimplemento tutti i suoi metodi (o almeno 2) d. All'inerno della funzione iterator() faccio restituire un'istanza della classe appena creata (non visibile all'utente finale) in modo tale che anche l'utente in qualche modo possa avere il suo bell'iteratore!!!...
Right? |
Yes, of course!! Esattamente quello che bisogna fare (o almeno che io ho fatto :P).
|
|
|
davide.mottin
|
Postato:
21 aprile 2005
Titolo:
Re: Ancora Iterator
|
|
|
Visto che ci sei, e spero di non approfittare della tua gentilezza, mi servirebbe un altro aiuto: Stavolta il metodo incriminato è Object[] toArrey (Object[] p0) e stando alla documentazione ufficiale io dovrei fare questo:
Returns an array containing all of the elements in this collection; the runtime type of the returned array is that of the specified array. If the collection fits in the specified array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the specified array and the size of this collection. If this collection fits in the specified array with room to spare (i.e., the array has more elements than this collection), the element in the array immediately following the end of the collection is set to null. This is useful in determining the length of this collection only if the caller knows that this collection does not contain any null elements.)
If this collection makes any guarantees as to what order its elements are returned by its iterator, this method must return the elements in the same order.
Like the toArray method, this method acts as bridge between array-based and collection-based APIs. Further, this method allows precise control over the runtime type of the output array, and may, under certain circumstances, be used to save allocation costs
Suppose l is a List known to contain only strings. The following code can be used to dump the list into a newly allocated array of String:
String[] x = (String[]) v.toArray(new String[0]); Note that toArray(new Object[0]) is identical in function to toArray().
Parameters: a - the array into which the elements of this collection are to be stored, if it is big enough; otherwise, a new array of the same runtime type is allocated for this purpose. Returns: an array containing the elements of this collection
Scusate per l'inglese ma è abbastanza comprensibile , la cosa che mi lascia sconcertato sono le parti sottolineate e che, se non ho capito male dicono che il TIPO dell'arrey passato deve coincidere con il TIPO DI RITORNO, ma adesso, come faccio sapere il tipo dell'arrey passato? se non sbaglio l'operatore instanceof mi permette di scrivere una cosa del tipo "a instanceof B" dove a è l'oggetto da verificare se è un'istanza della classe B, ma come faccio io sapere a priori cosa farà l'utente a runtime? Solo così infatti posso "ridimensionare l'arrey" a mio piacimento e con il tipo giusto, c'è per caso un metodo che mi permette di sapere questo o mi sono perso qualcosa.
Ho capito male il senso della implementazione o il mio resta solo un autolesionismo tanto che posso fare anche a meno di implementare quel metodo?
|
|
|
stefano.chirico
|
Postato:
21 aprile 2005
Titolo:
Re: Re: Ancora Iterator
|
|
|
Qui la vita si complica :P Questo metodo deve restituire un array i cui elementi sono dello stesso tipo e la grandezza è la stessa di quello passato come parametro. Se la dimensione è minore, invece, bisogna creare un array dello stesso tipo ma di dimensione adatta a contenere l'intera "collezione" (l'intero Stack). Se la dimensione è superiore, tutti gli elementi in eccesso andranno messi a null. Il problema e' che in Java un array puo essere di qualsiasi tipo (e quindi anche di classi future create dall'utente/programmatore). Sarebbe impossibile gestire tutte le classi esistenti attraverso instanceof. La tecnica che si deve utilizzare prende il nome di RTTI (RunTime Type Identification) che puo' sembrare un parolone, ma che alla fine Java rende semplice :P Esiste una classe particolare in Java (Class) che permette di scoprire tutte le informazioni relative a classi e oggetti direttamente a runtime. E' possibile creare, quindi, oggetti della classe desiderata anche se non si conosce la classe desiderata ;)
|
|
|
|
|