ATTENZIONE: il nuovo sito di riferimento per questa guida e altre cose più o meno interessanti è il mio BLOG

Indice
Prossimo capitolo - Leggere e scrivere file

Capitolo 6 - Collezioni di oggetti

Molto spesso si ha necessità di conservare degli oggetti in una struttura dati. La scelta migliore per semplicità e velocità è l'array, ma non sempre è applicabile.

La libreria java.util fornisce delle collezioni pronte all'uso, strutturate in una gerarchia che prevede tre interfacce principali - List, Set e Map - e varie implementazioni.

Un Set (insieme) è un contenitore che mantiene una sola copia dell'oggetto, mentre Map è un'associazione (funzione) chiave - valore.

Ecco un esempio di lista:

	List capitali = new ArrayList();

	capitali.add("Roma");
	capitali.add("Parigi");
5	capitali.add("Londra");

	System.out.println(capitali);
È opportuno usare le interfacce invece delle implementazioni (linea 1).

In linea 7 viene chiamato il metodo toString(), che fornisce una rappresentazione del contenuto della lista. Se si prova a fare lo stesso con un array si vede che toString() non fornisce la stessa informazione; in questo caso si possono usare i metodi statici toString(...) o deepToString(...) della classe Arrays.

Generics e autoboxing

Una collezione contiene Object, quindi quando si recuperano gli oggetti è necessario il casting - continuando l'esempio precedente:

	String it = (String) capitali.get(0);
Java 1.5 ha introdotto generics e autoboxing, che permettono un uso più diretto e sicuro delle collezioni:
	List<String> capitali = new ArrayList<String>();
In questo modo capitali non è più una lista di oggetti, ma di stringhe, quindi il casting non serve.

L'autoboxing (e specularmente unboxing) invece consente di creare liste di tipi primitivi:

	List<Integer> primi = new ArrayList<Integer>();
	primi.add(2); // autoboxing
e più in generale di usare un tipo primitivo quando viene richiesto un tipo wrapper (Integer, Float, ecc.) o Object o Number (superclassi).

Iteratori e nuovo for

Il modo standard di accedere agli elementi di una collezione è tramite un Iterator:

	Iterator i = capitali.iterator();

	while(i.hasNext())
		System.out.println(i.next());
In java 5 una collezione si può visitare molto più agevolmente con l'enhanced for, già visto in azione per gli array:
	for(String c : capitali)
	    System.out.println(c);

Costruiamo una pila

In conclusione di questo capitolo vediamo un semplice esempio di implementazione di pila generica - nel main() un esempio d'uso:

	import java.util.*;

	/** Pila generica.
	*   Usa la nuova (1.5) interfaccia Queue, implementata da LinkedList.
	*/
	public class Pila<T>	// notare il "segnaposto" per il tipo
	{
		private LinkedList<T> pila;

		/** Crea una pila vuota
		*/
		public Pila()
		{
			pila = new LinkedList<T>();
		}

		/** Mette un elemento in testa alla pila.
		* @param el l'elemento da inserire.
		*/
		public void push(T el)
		{
			pila.addFirst(el);
		}

		/** Estrae un elemento dalla pila.
		* @return L'elemento estratto.
		* @throws NoSuchElementException se la pila e' vuota.
		*/
		public T pop()
		{
			return pila.remove(); // Queue, Java 1.5+
		}

		public String toString()
		{
			return pila.toString();
		}

		/** MAIN - per test */
		public static void main(String... args)
		{
			// crea una pila vuota di Integer
			Pila<Integer> p = new Pila<Integer>();

			/* mette sulla pila 23, 0, -22
			   usa autoboxing, java 1.5 o superiore */
			p.push(23);
			p.push(0);
			p.push(-22);

			System.out.println(p);

			System.out.println(p.pop());
			System.out.println(p);

			p.pop();
			p.pop(); // ora la pila e' vuota!
			System.out.println(p);

			p.pop(); // lancia NoSuchElementException
		}
	}



Indice
Prossimo capitolo - Leggere e scrivere file