![]() ![]() |
|
![]() ![]() |
Supponiamo di voler riempire un array di interi con valori letti da input.
Quindi come prima cosa bisogna leggere la dimensione dell'array, in seguito dobbiamo leggere i singoli valori con i quali riempire le celle dell'array. Per accedere agli elementi di un array a usiamo un ciclo for con una variabile di controllo (usata come indice) che assume i valori da 0 al valore di a.length-1 (estremi inclusi).
Supponiamo adesso di voler anche stampare l' array dopo averlo costruito. Un array a è un oggetto e se si tenta di stamparlo direttamente con System.out.println(a) il risultato non è quello atteso. Ad esempio, si provi a eseguire il seguente programma:
Per stampare l'array possiamo usare un ciclo for che stampa tutti gli elementi dell'array (separati da spazi), delimitati dalle parentesi quadre:
|
![]() ![]() |
|
![]() ![]() |
La parte del codice del programma RiempiStampaArray che riempie l'array, o quella che ne stampa gli elementi potrebbero essere utili in altri programmi, ma non sono riutilizzabili: andrebbero copiate. Riscriviamole come metodi (statici) di una opportuna classe, ArrayUtils, in modo da poterli riusare liberamente. Si noti che:
Per testare i metodi occorre scrivere una classe principale (cioè con il metodo main):
|
![]() ![]() |
|
![]() ![]() |
Un tipico uso di un array consiste nello
scandire (o visitare) in sequenza i suoi elementi, per esaminarli,
modificarli, o confrontarli...
Come abbiamo già visto per la lettura e scrittura, per scandire TUTTI gli elementi di un array a è naturale usare un comando for con una variabile di controllo che assume i valori da 0 al valore di a.length-1 (estremi inclusi). Vedremo vari esempi di scansione di array con comandi for:
Vedremo anche delle soluzioni alternative:
Per ognuno di questi problemi presenteremo un metodo statico della classe ArrayUtils: sfrutteremo il fatto che gli array possono essere passati come parametri, e possono essere restituiti come risultato di un metodo (come già visto per i metodi fill_int e print). I metodi della classe ArrayUtils sono stati scelti per illustrare come sia possibile:
|
![]() ![]() |
|
![]() ![]() |
La ricerca del massimo elemento di un dato insieme di valori è un'operazione piuttosto frequente, ad esempio nella gestione di strutture con priorità. Per questo motivo la classe ArrayUtils realizza un metodo (statico) che preso un array di interi ne individua e restituisce il massimo valore. Si noti che:
Per testare il metodo occorre scrivere una classe principale (cioè con il metodo main):
|
![]() ![]() |
|
![]() ![]() |
I prossimi metodi di ArrayUtils calcolano il massimo, ma usando la ricorsione invece di un for. Il primo metodo, che è public, non fa altro che invocare un metodo ausiliario dichiarato private, quindi non invocabile all'esterno della classe. Il metodo ausiliario ha due parametri: concettualmente maxRecursive(array, i) restituisce il massimo degli elementi dell'array a partire dalla posizione i. Assumendo che 0 <= i <= array.length, il metodo usa la seguente definizione ricorsiva:
|
![]() ![]() |
|
![]() ![]() |
Il metodo sort di ArrayUtils ordina in modo crescente il contenuto dell'array passato per argomento, utilizzando due cicli for annidati.
L'algoritmo consiste di un ciclo annidato: si scorrono gli elementi dell'array confrontando l'elemento in posizione i con ciascuno degli elementi che lo seguono, scambiando i valori quando non sono ordinati. Questo algoritmo di ordinamento è chiamato insertion sort e non è particolarmente efficiente. Ad esempio provate a pensare cosa succede se gli elementi sono inizialmente disposti in ordine inverso, dal più grande al più piccolo. Esistono numerosi altri algoritmi di ordinamento più efficienti: ne vedrete alcuni a Fondamenti di Programmazione. La cosa importante da notare è che gli scambi effettuati dal metodo si ripercuotono sull'array passato come argomento: questo è possibile perché il metodo conosce il riferimento all'oggetto-array. |
![]() ![]() |
|
![]() ![]() |
Il metodo clone di ArrayUtils restituisce una copia (clone) dell'array passato per argomento, cioè un array avente la stessa lunghezza e gli stessi elementi. .
Si noti che poiché gli array sono oggetti, le variabili di tipo array contengono dei riferimenti. Quindi se si assegna una variabile di tipo array ad un'altra, si crea solo una copia del riferimento, non dell'array.
|
![]() ![]() |
|
![]() ![]() |
La classe ArrayUtils realizza anche metodi statici per riempire e stampare array di stringhe. Il codice è analogo a quello che abbiamo visto per array di interi (ma la stampa avviene con un elemento per riga):
Esempio: Adesso che finalmente abbiamo tutti gli elementi per interpretare il parametro args del metodo main possiamo scrivere facilmente un programma che stampa eventuali argomenti passati da linea di comando. Ad esempio: > java TestArgs uno due "t r e" ...
Notare che è possibile definire entrambi i metodi print (per array di interi e di stringhe) nello stesso file, perché il tipo del parametro usato in una generica invocazione permette di distinguere quale dei due metodi usare: uno si applica solo ad array di interi, l'altro solo ad array di stringhe. |
![]() ![]() |
|
![]() ![]() |
Molti linguaggi mettono a disposizione un quarto costrutto iterativo, chiamato for-each, che permette di iterare sopra collezioni di dati (es. array, tipi enumerativi, insiemi, liste, ...) usando una sintassi particolarmente agevole e compatta. Dalla versione 5.0 anche Java ha introdotto un costrutto simile, chiamato for generalizzato, con una sintassi diversa da quella usata in altri linguaggi (per non introdurre una nuova parole chiave creando problemi di backward compatibility). La sintassi è:
Questo comando è equivalente a:
Anche se il ciclo scorre tutti gli elementi dell'array, assegnandone il valore di volta in volta alla variabile <nome_variabile>, notate che la posizione del valore nell'array non è esplicitata nel codice del for generalizzato e quindi non è riferibile nel <corpo> del ciclo. Ne consegue che, in questo caso, il for generalizzato può essere usato unicamente per esaminare i valori contenuti nell'array, non per modificarne il contenuto. Come esempi d'uso, vediamo due metodi: uno per stampare un array di stringhe e l'altro per calcolare la somma dei valori contenuti in un array di interi. Come esercizio, provate a confrontare il codice con quello che usa il ciclo for classico.
|