Uno dei problemi più complicati per i programmatori, e al contempo uno dei campi di ricerca più interessanti, è senz'altro quello che riguarda la scelta delle strutture dati, la quale non può prescindere dal problema che si deve risolvere. Nel mondo
Java, prima del rilascio del JDK 1.2, esistevano pochi strumenti della libreria standard, soltanto un piccolo set di classi relative a strutture quali vettori, pile,
bitset. Con l'avvento di JDK 1.2 si è assistito invece alla crescita della stessa libreria standard, sulle orme della
STL del C++, ma con l'obiettivo di rendere il tutto più semplice dal punto di vista dell'utilizzo e dell'apprendimento. In questo articolo si vedrà come usare al meglio le mappe.
Una mappa non è altro che una collezione di oggetti e mira a rendere veloci ed efficienti operazioni quali inserimento e ricerca di elementi. In particolare, una mappa memorizza coppie chiave/valore e ha due implementazioni, del tutto generali:
HashMap e
TreeMap. Quest'ultima realizza un ordinamento ad albero, in particolare un albero di ricerca che velocizza appunto le operazioni di
searching di elementi. L'
HashMap sfrutta invece l'ordinamento delle chiavi basato sui codici
hash.
Sia chiaro come l'ordinamento è riferito alle chiavi e non ai valori; per questi ultimi non sono previste operazioni di confronto (al massimo, la libreria
Java permette di verificarne l'esistenza). Il codice per costruire una mappa, ad esempio di tipo
HashMap, è semplicissimo:
<span style="font-size:1.0em">Map nomeMappa = new HashMap();</span>
Per inserire un oggetto si usa il metodo
put(chiave, oggetto); si presti attenzione al fatto che il metodo sovrascrive l'oggetto vecchio col nuovo, qualora la chiave sia già presente. Difatti
put restituisce il vecchio valore della chiave oppure
null se la chiave non era presente nella mappa. Le chiavi devono essere univoche e quindi all'interno di una mappa non possono esistere due elementi con la stessa chiave. Può allora essere utile verificare la presenza di una chiave con il metodo
containsKey(chiave), che restituisce
true se la chiave è presente.
Un metodo analogo è
containsValue(oggetto), che verifica la presenza di un oggetto (di un valore). Per recuperare un oggetto si usa il metodo
get(chiave), cui va passata la chiave relativa all'oggetto, che intendiamo recuperare; se nella mappa non esiste nessun oggetto con la chiave passata, allora il metodo restituisce
null. E' possibile rimuovere gli elementi da una mappa chiamando il metodo
remove(chiave), mentre per conoscere il numero di elementi memorizzati nella mappa possiamo usare il metodo
size(). Di seguito, è presentato un esempio completo. Si suppone di voler gestire una libreria, si crea una classe
Book del tipo:
<span style="font-size:1.0em">
class Book { public Book(String t, String a) { title = t;
author = a;
}
public String toString() { return "[title=" + title + " | author=" + author + " ]";
}
private String title;
private String author;
}
</span>
Ed ora un semplicissimo programma per verificare la bontà di questa struttura dati:
<span style="font-size:1.0em">
public class BookTest { public static void main(String[] args) { Map books = new HashMap();
books.put("8838650675", new Book("Introduzione a UML", "Bennett")); books.put("8873038506", new Book("Programmare in C", "Aitken")); books.put("8871922042", new Book("Ingegneria del software", "Ghezzi"));
//stampiamo gli elementi
System.out.println(books);
//aggiorniamo un elemento sfruttando il metodo put
books.put("8871922042", new Book("Ingegneria del software - Fondamenti e Principi", "Ghezzi"));
//visualizziamo l'aggiornamento
System.out.println(books.get("8871922042")); }
}
</span>