|
Abbiamo già ampiamente visto e illustrato il funzionamento degli array. Ho anche già detto più volte come essi non siano
sempre la soluzione migliore ai nostri problemi di immagazzinamento dati. Infatti, è difficile deciderne la dimensione quando non
si sa a priori quanti dati verranno immessi: inoltre, è oneroso in termini di tempo e risorse modificarna la lunghezza mentre il
programma gira; e nel caso contrario, è molto limitativo concedere all'utente un numero prefissato massimo di valori. A questo
proposito, ci vengono in aiuto delle classi già presenti nelle librerie standard del Framework .NET che aiutano proprio a gestire
insiemi di elementi di lunghezza variabile. Di seguito ne propongo una breve panoramica.
ArrayList
Si tratta di una classe per la gestione di liste di elementi. Essendo un tipo reference, quindi, segue che ogni oggetto dichiarato
come di tipo ArrayList debba essere inizializzato prima dell'uso con un adeguato costruttore. Una volta creata un'istanza, la si può
utilizzare normalmente. La differenza con l'Array risiede nel fatto che l'ArrayList, all'inizio della sua "vita", non contiene nessun
elemento, e, di conseguenza occupa relativamente meno memoria. Infatti, quando noi inizializziamo un array, ad esempio così:
Dim A(100) As Int32
nel momento in cui questo codice viene eseguito, il programma richiede 101 celle di memoria della grandezza di 4 bytes ciascuna da riservare
per i propri dati: che esse siano impostate o meno (all'inizio sono tutti 0), non ha importanza, perchè A occuperà sempre la
stessa quantità di memoria. Al contrario l'ArrayList non "sa" nulla su quanti dati vorremmo introdurre, quindi, ogni volta che
un nuovo elemento viene introdotto, esso si espande allocando dinamicamente nuova memoria solo se ce n'è bisogno. In questo
risiede la potenza delle liste.
Per aggiungere un nuovo elemento all'arraylist bisogna usare il metodo d'istanza Add, passandogli come parametro il valore da aggiungere.
Ecco un esempio:
Module Module1
Class Cube
'...
End Class
Sub Main()
'Crea un nuovo arraylist
Dim Cubes As New ArrayList
Console.WriteLine("Inserismento cubi:")
Console.WriteLine()
Dim Cmd As Char
Do
Console.WriteLine()
Dim C As New Cube
'Scrive il numero del cubo
Console.Write((Cubes.Count + 1) & " - ")
Console.Write("Lato (m): ")
C.SideLength = Console.ReadLine
Console.Write(" Densità (kg/m3): ")
C.Density = Console.ReadLine
'Aggiunge un nuovo cubo alla collezione
Cubes.Add(C)
Console.WriteLine("Termina inserimento? y/n")
Cmd = Console.ReadKey().KeyChar
Loop Until Char.ToLower(Cmd) = "y"
'Calcola la massa totale di tutti i cubi nella lista
Dim TotalMass As Single = 0
'Notate che l'ArrayList si può usare come un
'normale array. L'unica differenza sta nel fatto che
'esso espone la proprietà Count al posto di Length.
'In genere, tutte le liste espongono Count, che comunque
'ha sempre lo stesso significato: restituisce il numero
'di elementi nella lista
For I As Int32 = 0 To Cubes.Count - 1
TotalMass += Cubes(I).Mass
Next
Console.WriteLine("Massa totale: " & TotalMass)
Console.ReadKey()
End Sub
End Module
Allo stesso modo, è possibile rimuovere o inserire elementi con altri metodi:
- Remove(x) : rimuove l'elemento x dall'arraylist
- RemoveAt(x) : rimuove l'elemento che si trova nella posizione x dell'ArrayList
- IndexOf(x) : restituisce l'indice dell'elemento x
- Contains(x) : restituisce True se x ? contenuto nell'ArrayList, altrimenti False
- Clear : pulisce l'arraylist eliminando ogni elemento
- Clone : restituisce una copia esatta dell'ArrayList. Questo argomento verrà discusso più in là nella guida.
Hashtable
L'Hashtable possiede un meccanismo di allocazione della memoria simile a quello di un ArrayList, ma è concettualmente differente in termini
di utilizzo. L'ArrayList, infatti, non si discosta molto, parlando di pratica, da un Array - e infatti vediamo questa somiglianza nel nome:
ogni elemento è pur sempre contraddistinto da un indice, e mediante questo è possibile ottenrne o modificarne il valore;
inoltre, gli indici sono sempre su base 0 e sono sempre numeri interi, generalmente a 32 bit. Quest'ultima peculiarità di permette di
dire che in un ArrayList gli elementi sono logicamente ordinati. In un Hashtable, al contrario, tutto ciò che ho esposto fin'ora non
vale. Questa nuova classe si basa sull'associazione di una chiave (key) con un valore (value). Quando si aggiunge un nuovo
elemento all'Hashtable, se ne deve specificare la chiave, che può essere qualsiasi cosa: una stringa, un numero, una data, un
oggetto, eccetera... Quando si vuole ripescare quello stesso elemento bisogna usare la chiave che gli era stata associata. Usando numeri
interi come chiavi si può simulare il comportamento di un ArrayList, ma il meccanismo intrinseco di questo tipo di collezione
rimane pur sempre molto diverso. Ecco un esempio:
'Hashtabel contenente alcuni materiali e le
'relative densità
Dim H As New Hashtable
'Aggiunge un elemento, contraddistinto da una chiave stringa
H.Add("Acqua", 1000)
H.Add("Alluminio", 2700)
H.Add("Argento", 10490)
H.Add("Nichel", 8800)
'...
'Possiamo usare l'hashtable per associare
'facilmente densità ai nostri cubi:
Dim C As New Cube(1, H("Argento"))
Notare che è anche possibile fare il contrario, ossia:
Dim H As New Hashtable
H.Add(1000, "Acqua")
H.Add(2700, "Alluminio")
H.Add(10490, "Argento")
H.Add(8800, "Nichel")
In quest'ultimo esempio, l'Hashtable contiene quattro chiavi costituite da valori numerici: non è comunque possibile ciclarle usando
un For. Infatti, negli ArrayList e negli Array, abbiamo la garanzia che se la collezione contiene 8 elementi, ad esempio, ci saranno sempre
degli indici interi validi tra 0 e 7; con gli Hashtable, al contrario, non possiamo desumere nulla sulle chiavi osservando il semplice
numero di elementi. In genere, per iterare attraverso gli elementi di un Hashtable, si usano dei costrutti For Each:
For Each V As String In H.Values
'Enumera tutti gli elementi di H
' V = "Acqua", "Alluminio", "Argento", ...
Next
For Each K As Int32 In H.Keys
'Enumera tutte le chiavi
'K = 1000, 2700, 10490, ...
Next
Per l'iterazione ci vengono in aiuto le proprietà Values e Keys, che contengono rispettivamente tutti i valori e tutte le chiavi
dell'Hashtable: queste collezioni sono a sola lettura, ossia non è possibile modificarle in alcun modo. D'altronde, è abbastanza
ovvio: se aggiungessimo una chiave l'Hashtable non saprebbe a quale elemento associarla. L'unico modo per modificarle è indiretto e
consiste nell'usare metodi come Add, Remove, eccetera... che sono poi gli stessi di ArrayList.
SortedList
Si comporta esattamente come un Hashtable, solo che gli elementi vengono mantenuti sempre in ordine secondo la chiave.
|
|