Introduzione alle Collezioni in Java
- Il Framework delle Collezioni in Java standardizza la gestione dei gruppi di oggetti.
- Le collezioni sono state introdotte in Java a partire da J2SE 1.2 per risolvere problemi di gestione e interoperabilità tra gruppi di oggetti.
- Le interfacce principali del Framework delle Collezioni includono
Collection
,List
,Set
,Queue
,Deque
,SortedSet
eNavigableSet
. - Le collezioni possono essere modificabili o non modificabili, a seconda della loro implementazione.
- Gli algoritmi per operare sulle collezioni sono definiti nella classe
Collections
. - Gli iteratori, come
Iterator
,ListIterator
eSpliterator
, forniscono un modo standardizzato per accedere agli elementi delle collezioni. - Le mappe, che memorizzano coppie chiave/valore, sono parte del Framework delle Collezioni ma non sono considerate collezioni nel senso stretto del termine.
- Il Framework delle Collezioni è progettato per essere ad alte prestazioni, facilmente estendibile e interoperabile tra diverse implementazioni.
Panoramica delle Collezioni
Il Framework delle Collezioni Java standardizza il modo in cui i gruppi di oggetti vengono gestiti dai nostri programmi.
Le collezioni non facevano parte del rilascio originale di Java, ma sono state aggiunte da J2SE 1.2. Prima del Framework delle Collezioni, Java forniva classi ad hoc come Dictionary
, Vector
, Stack
e Properties
per memorizzare e manipolare gruppi di oggetti. Sebbene queste classi fossero molto utili, mancavano di un tema centrale e unificante.
Il modo in cui si utilizzava Vector
era diverso dal modo in cui si utilizzava Properties
, per esempio. Inoltre, questo primo approccio ad hoc non era progettato per essere facilmente esteso o adattato. Le collezioni sono state una risposta a questi (e altri) problemi.
Il Framework delle Collezioni è stato progettato per soddisfare diversi obiettivi. Primo, il framework doveva essere ad alte prestazioni. Le implementazioni per le collezioni fondamentali (array dinamici, liste collegate, alberi e tabelle hash) sono altamente efficienti. Raramente, se mai, abbiamo bisogno di codificare manualmente uno di questi "motori di dati". Secondo, il framework doveva permettere a diversi tipi di collezioni di funzionare in modo simile e con un alto grado di interoperabilità. Terzo, estendere e/o adattare una collezione doveva essere facile. A questo scopo, l'intero Framework delle Collezioni è costruito su un insieme di interfacce standard.
Diverse implementazioni standard (come LinkedList
, HashSet
e TreeSet
) di queste interfacce sono fornite e si possono utilizzare così come sono. Possiamo anche implementare la nostra collezione, se scegliamo di farlo. Varie implementazioni per scopi speciali sono create per la nostra comodità, e alcune implementazioni parziali sono fornite per rendere più facile creare la nostra classe di collezione. Infine, sono stati aggiunti meccanismi che permettono l'integrazione degli array standard nel Framework delle Collezioni.
Gli algoritmi sono un'altra parte importante del meccanismo delle collezioni. Gli algoritmi operano sulle collezioni e sono definiti come metodi statici all'interno della classe Collections
. Quindi, sono disponibili per tutte le collezioni. Ogni classe di collezione non ha bisogno di implementare le proprie versioni. Gli algoritmi forniscono un mezzo standard per manipolare le collezioni.
Un altro elemento strettamente associato al Framework delle Collezioni è l'interfaccia Iterator
. Un iteratore offre un modo standardizzato e generico per accedere agli elementi all'interno di una collezione, uno alla volta. Quindi, un iteratore fornisce un mezzo per enumerare i contenuti di una collezione. Poiché ogni collezione fornisce un iteratore, gli elementi di qualsiasi classe di collezione possono essere accessibili attraverso i metodi definiti da Iterator
. Quindi, con solo piccole modifiche, il codice che scorre un insieme può anche essere utilizzato per scorrere una lista, per esempio.
JDK 8 ha aggiunto un altro tipo di iteratore chiamato spliterator. In breve, gli spliterator sono iteratori che forniscono supporto per l'iterazione parallela. Le interfacce che supportano gli spliterator sono Spliterator
e diverse interfacce annidate che supportano i tipi primitivi. Sono disponibili anche interfacce di iteratori progettate per l'uso con tipi primitivi, come PrimitiveIterator
e PrimitiveIterator.OfDouble
.
Oltre alle collezioni, il framework definisce diverse interfacce e classi per le mappe. Le mappe memorizzano coppie chiave/valore. Sebbene le mappe facciano parte del Framework delle Collezioni, non sono "collezioni" nell'uso stretto del termine. Possiamo tuttavia ottenere una vista-collezione di una mappa. Tale vista contiene gli elementi dalla mappa memorizzati in una collezione. Quindi, possiamo elaborare i contenuti di una mappa come una collezione, se scegliamo di farlo.
Il meccanismo delle collezioni è stato adattato a posteriori ad alcune delle classi originali definite da java.util
in modo che anch'esse potessero essere integrate nel nuovo sistema. È importante capire che sebbene l'aggiunta delle collezioni abbia alterato l'architettura di molte delle classi di utilità originali, non ha causato la deprecazione di nessuna. Le collezioni forniscono semplicemente un modo migliore di fare diverse cose.
Le Interfacce delle Collezioni
Il Collections Framework definisce diverse interfacce principali. Iniziare con le interfacce delle collezioni è necessario perché determinano la natura fondamentale delle classi delle collezioni. In altre parole, le classi concrete forniscono semplicemente diverse implementazioni delle interfacce standard.
Le interfacce che sostengono le collezioni sono riassunte nella seguente tabella:
Interfaccia | Descrizione |
---|---|
Collection |
Consente di lavorare con gruppi di oggetti; si trova in cima alla gerarchia delle collezioni. |
Deque |
Estende Queue per gestire una coda a doppia estremità. |
List |
Estende Collection per gestire sequenze (liste di oggetti). |
NavigableSet |
Estende SortedSet per gestire il recupero di elementi basato su ricerche di corrispondenza più vicina. |
Queue |
Estende Collection per gestire tipi speciali di liste in cui gli elementi vengono rimossi solo dalla testa. |
Set |
Estende Collection per gestire insiemi, che devono contenere elementi unici. |
SortedSet |
Estende Set per gestire insiemi ordinati. |
Oltre alle interfacce delle collezioni, le collezioni utilizzano anche le interfacce Comparator
, RandomAccess
, Iterator
, ListIterator
e Spliterator
, che sono descritte in profondità nelle prossime lezioni. In breve, Comparator
definisce come due oggetti vengono confrontati; Iterator
, ListIterator
e Spliterator
enumerano gli oggetti all'interno di una collezione. Implementando RandomAccess
, una lista indica che supporta l'accesso casuale efficiente ai suoi elementi.
Per fornire la massima flessibilità nel loro utilizzo, le interfacce delle collezioni consentono ad alcuni metodi di essere opzionali. I metodi opzionali consentono di modificare il contenuto di una collezione. Le collezioni che supportano questi metodi sono chiamate modificabili. Le collezioni che non consentono di modificare il loro contenuto sono chiamate non modificabili. Se viene fatto un tentativo di utilizzare uno di questi metodi su una collezione non modificabile, viene lanciata un'UnsupportedOperationException
. Tutte le collezioni integrate sono modificabili.
A partire dalla prossima lezione inizieremo lo studio delle interfacce delle collezioni partendo dall'interfaccia Collection
.