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 Int32nel 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 ModuleAllo 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, ... NextPer 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.A cura di: Il Totem