L'interfaccia Map in Java
- L'interfaccia
Map
in Java rappresenta una collezione di coppie chiave/valore, dove le chiavi sono uniche e i valori possono essere duplicati. - Le mappe non implementano l'interfaccia
Iterable
, quindi non possono essere iterate direttamente con un ciclofor
in stile for-each. - Le interfacce principali relative a
Map
includonoMap.Entry
,NavigableMap
eSortedMap
. - Le classi che implementano l'interfaccia
Map
includonoHashMap
,TreeMap
,LinkedHashMap
,IdentityHashMap
eEnumMap
.
Lavorare con le Map
Una mappa o Map
è un oggetto che memorizza associazioni tra chiavi e valori, o coppie chiave/valore. Data una chiave, è possibile trovare il suo valore. Sia le chiavi che i valori sono oggetti. Le chiavi devono essere uniche, ma i valori possono essere duplicati. Alcune mappe possono accettare una chiave null
e valori null
, altre no.
C'è un punto chiave sulle mappe che è importante menzionare dall'inizio: non implementano l'interfaccia Iterable
. Questo significa che non è possibile scorrere una mappa utilizzando un ciclo for
in stile for-each. Inoltre, non è possibile ottenere un iteratore per una mappa. Tuttavia, come vedremo presto, è possibile ottenere una vista-collezione di una mappa, che permette l'uso sia del ciclo for
che di un iteratore.
Le Interfacce relative a Map
Poiché le interfacce Map
definiscono il carattere e la natura delle mappe, questa discussione sulle mappe inizia con esse.
Le seguenti interfacce supportano le mappe:
Interfaccia | Descrizione |
---|---|
Map |
Mappa chiavi uniche a valori. |
Map.Entry |
Descrive un elemento (una coppia chiave/valore) in una mappa. Questa è un'interfaccia annidata di Map . |
NavigableMap |
Estende SortedMap per gestire il recupero di voci basato su ricerche di corrispondenza più vicina. |
SortedMap |
Estende Map in modo che le chiavi siano mantenute in ordine crescente. |
Ogni interfaccia viene esaminata di seguito.
L'Interfaccia Map
L'interfaccia Map
mappa chiavi uniche a valori. Una chiave è un oggetto che usiamo per recuperare un valore in un momento successivo. Dato una chiave e un valore, possiamo memorizzare il valore in un oggetto Map
. Dopo che il valore è memorizzato, possiamo recuperarlo utilizzando la sua chiave.
Map
è generica ed è dichiarata come mostrato qui:
interface Map<K, V>
Qui, K
specifica il tipo delle chiavi, e V
specifica il tipo dei valori.
I metodi dichiarati da Map
sono riassunti nella tabella seguente:
Metodo | Descrizione |
---|---|
void clear() |
Rimuove tutte le coppie chiave/valore dalla mappa chiamante. |
default V compute(K k, BiFunction<? super K, ? super V, ? extends V> func) |
Chiama func per costruire un nuovo valore. Se func restituisce un valore non null , la nuova coppia chiave/valore viene aggiunta alla mappa, qualsiasi accoppiamento preesistente viene rimosso, e il nuovo valore viene restituito. Se func restituisce null , qualsiasi accoppiamento preesistente viene rimosso, e null viene restituito. |
default V computeIfAbsent(K k, Function<? super K, ? extends V> func) |
Restituisce il valore associato alla chiave k . Altrimenti, il valore viene costruito attraverso una chiamata a func e l'accoppiamento viene inserito nella mappa e il valore costruito viene restituito. Se nessun valore può essere costruito, null viene restituito. |
default V computeIfPresent(K k, BiFunction<? super K, ? super V, ? extends V> func) |
Se k è nella mappa, un nuovo valore viene costruito attraverso una chiamata a func e il nuovo valore sostituisce il vecchio valore nella mappa. In questo caso, il nuovo valore viene restituito. Se il valore restituito da func è null , la chiave e il valore esistenti vengono rimossi dalla mappa e null viene restituito. |
boolean containsKey(Object k) |
Restituisce true se la mappa chiamante contiene k come chiave. Altrimenti, restituisce false . |
boolean containsValue(Object v) |
Restituisce true se la mappa contiene v come valore. Altrimenti, restituisce false . |
static <K, V> Map<K, V> copyOf(Map<? extends K, ? extends V> from) |
Restituisce una mappa che contiene le stesse coppie chiave/valore di quella specificata da from. La mappa restituita è non modificabile e basata sui valori. Chiavi o valori null non sono consentiti. |
static <K, V> Map.Entry<K, V> entry(K k, V v) |
Restituisce una voce di mappa non modificabile basata sui valori composta dalla chiave e dal valore specificati. Una chiave o un valore null non è consentito. |
Set<Map.Entry<K, V>> entrySet() |
Restituisce un Set che contiene le voci nella mappa. Il set contiene oggetti di tipo Map.Entry . Quindi, questo metodo fornisce una vista-set della mappa chiamante. |
boolean equals(Object obj) |
Restituisce true se obj è una Map e contiene le stesse voci. Altrimenti, restituisce false . |
default void forEach(BiConsumer<? super K, ? super V> action) |
Esegue action su ogni elemento nella mappa chiamante. Verrà lanciata una ConcurrentModificationException se un elemento viene rimosso durante il processo. |
V get(Object k) |
Restituisce il valore associato alla chiave k . Restituisce null se la chiave non viene trovata. |
default V getOrDefault(Object k, V defVal) |
Restituisce il valore associato a k se è nella mappa. Altrimenti, defVal viene restituito. |
int hashCode() |
Restituisce il codice hash per la mappa chiamante. |
boolean isEmpty() |
Restituisce true se la mappa chiamante è vuota. Altrimenti, restituisce false . |
Set<K> keySet() |
Restituisce un Set che contiene le chiavi nella mappa chiamante. Questo metodo fornisce una vista-set delle chiavi nella mappa chiamante. |
default V merge(K k, V v, BiFunction<? super V, ? super V, ? extends V> func) |
Se k non è nella mappa, l'accoppiamento k,v viene aggiunto alla mappa. In questo caso, v viene restituito. Altrimenti, func restituisce un nuovo valore basato sul vecchio valore, la chiave viene aggiornata per utilizzare questo valore, e merge() restituisce questo valore. Se il valore restituito da func è null , la chiave e il valore esistenti vengono rimossi dalla mappa e null viene restituito. |
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, ...) |
Crea una mappa non modificabile basata sui valori contenente le voci specificate in lista-parametri . Chiavi o valori null non sono consentiti. Vengono fornite molte versioni sovraccaricate. Vedere la discussione nel testo per i dettagli. |
static <K, V> Map<K, V> ofEntries(Map.Entry<? extends K, ? extends V>... voci) |
Restituisce una mappa non modificabile basata sui valori che contiene le mappature chiave/valore descritte dalle voci passate in voci . Chiavi o valori null non sono consentiti. |
V put(K k, V v) |
Inserisce una voce nella mappa chiamante, sovrascrivendo qualsiasi valore precedente associato alla chiave. La chiave e il valore sono k e v , rispettivamente. Restituisce null se la chiave non esisteva già. Altrimenti, il valore precedente collegato alla chiave viene restituito. |
void putAll(Map<? extends K, ? extends V> m) |
Inserisce tutte le voci da m in questa mappa. |
default V putIfAbsent(K k, V v) |
Inserisce la coppia chiave/valore nella mappa chiamante se questo accoppiamento non è già presente o se il valore esistente è null. Restituisce il vecchio valore. Il valorenull viene restituito quando non esiste una mappatura precedente, o il valore è null. |
V remove(Object k) |
Rimuove la voce la cui chiave è uguale a k. |
default boolean remove(Object k, Object v) |
Se la coppia chiave/valore specificata da k e v è nella mappa chiamante, viene rimossa e true viene restituito. Altrimenti, false viene restituito. |
default boolean replace(K k, V oldV, V newV) |
Se la coppia chiave/valore specificata da k e oldV è nella mappa chiamante, il valore viene sostituito da newV e true viene restituito. Altrimenti false viene restituito. |
default V replace(K k, V v) |
Se la chiave specificata da k è nella mappa chiamante, il suo valore viene impostato a v e il valore precedente viene restituito. Altrimenti,null viene restituito. |
default void replaceAll(BiFunction<? super K, ? super V, ? extends V> func) |
Esegue func su ogni elemento della mappa chiamante, sostituendo l'elemento con il risultato restituito da func. Verrà lanciata una ConcurrentModificationException se un elemento viene rimosso durante il processo. |
int size() |
Restituisce il numero di coppie chiave/valore nella mappa. |
Collection<V> values() |
Restituisce una collezione contenente i valori nella mappa. Questo metodo fornisce una vista-collezione dei valori nella mappa. |
Diversi metodi lanciano una ClassCastException
quando un oggetto è incompatibile con gli elementi in una mappa. Viene lanciata una NullPointerException
se viene fatto un tentativo di utilizzare un oggetto null
e null
non è consentito nella mappa. Viene lanciata una UnsupportedOperationException
quando viene fatto un tentativo di modificare una mappa non modificabile. Viene lanciata una IllegalArgumentException
se viene utilizzato un argomento non valido.
Le mappe ruotano attorno a due operazioni di base: get()
e put()
. Per inserire un valore in una mappa, utilizziamo put()
, specificando la chiave e il valore. Per ottenere un valore, chiamiamo get()
, passando la chiave come argomento. Il valore viene restituito.
Come menzionato in precedenza, sebbene faccia parte del Collections Framework, le mappe non sono, esse stesse, collezioni perché non implementano l'interfaccia Collection
. Tuttavia, possiamo ottenere una vista-collezione di una mappa. Per fare questo, possiamo utilizzare il metodo entrySet()
. Restituisce un Set
che contiene gli elementi nella mappa. Per ottenere una vista-collezione delle chiavi, utilizziamo keySet()
. Per ottenere una vista-collezione dei valori, utilizziamo values()
. Per tutte e tre le viste-collezione, la collezione è supportata dalla mappa. Modificare una influisce sull'altra. Le viste-collezione sono il mezzo attraverso il quale le mappe sono integrate nel più ampio Collections Framework.
A partire da JDK 9, Map
include il metodo factory of()
, che ha un numero di overload. Ogni versione restituisce una mappa non modificabile, basata su valore che è composta dagli argomenti che le vengono passati. Lo scopo principale di of()
è fornire un modo conveniente ed efficiente per creare una piccola Map
. Ci sono 11 overload di of()
. Uno non prende argomenti e crea una mappa vuota. È mostrato qui:
static <K, V> Map<K, V> of()
Dieci overload prendono da 1 a 10 argomenti e creano una lista che contiene gli elementi specificati. Sono mostrati qui:
static <K, V> Map<K, V> of(K k1, V v1)
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2)
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3)
...
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10)
Per tutte le versioni, chiavi e/o valori null
non sono consentiti. In tutti i casi, l'implementazione di Map
non è specificata.
L'Interfaccia SortedMap
L'interfaccia SortedMap
estende Map
. Garantisce che le voci siano mantenute in ordine crescente basato sulle chiavi. SortedMap
è generica ed è dichiarata come mostrato qui:
interface SortedMap<K, V>
Qui, K
specifica il tipo delle chiavi, e V
specifica il tipo dei valori.
I metodi aggiunti da SortedMap
sono riassunti nella tabella seguente:
Metodo | Descrizione |
---|---|
Comparator<? super K> comparator() |
Restituisce il comparatore della mappa ordinata invocante. Se l'ordinamento naturale è usato per la mappa invocante, viene restituito null . |
K firstKey() |
Restituisce la prima chiave nella mappa invocante. |
SortedMap<K, V> headMap(K fine) |
Restituisce una mappa ordinata per quelle voci della mappa con chiavi che sono minori di fine . |
K lastKey() |
Restituisce l'ultima chiave nella mappa invocante. |
SortedMap<K, V> subMap(K inizio, K fine) |
Restituisce una mappa contenente quelle voci con chiavi che sono maggiori o uguali a inizio e minori di fine . |
SortedMap<K, V> tailMap(K inizio) |
Restituisce una mappa contenente quelle voci con chiavi che sono maggiori o uguali a inizio . |
Diversi metodi lanciano una NoSuchElementException
quando non ci sono elementi nella mappa invocante. Una ClassCastException
viene lanciata quando un oggetto è incompatibile con gli elementi in una mappa. Una NullPointerException
viene lanciata se viene fatto un tentativo di usare un oggetto null
quando null
non è consentito nella mappa. Una IllegalArgumentException
viene lanciata se viene usato un argomento non valido.
Le mappe ordinate permettono manipolazioni molto efficienti di sotto-mappa (in altre parole, sottoinsiemi di una mappa). Per ottenere una sotto-mappa, bisogna utilizzare headMap()
, tailMap()
, o subMap()
. La sotto-mappa restituita da questi metodi è supportata dalla mappa invocante. Cambiare una cambia l'altra. Per ottenere la prima chiave nell'insieme, chiamare firstKey()
. Per ottenere l'ultima chiave, usare lastKey()
.
L'Interfaccia NavigableMap
L'interfaccia NavigableMap
estende SortedMap
e dichiara il comportamento di una mappa che supporta il recupero di voci basato sulla corrispondenza più vicina a una chiave o chiavi date. NavigableMap
è un'interfaccia generica che ha questa dichiarazione:
interface NavigableMap<K,V>
Qui, K
specifica il tipo delle chiavi, e V
specifica il tipo dei valori associati alle chiavi. Oltre ai metodi che eredita da SortedMap
, NavigableMap
aggiunge quelli riassunti nella tabella seguente:
Metodo | Descrizione |
---|---|
Map.Entry<K, V> ceilingEntry(K obj) |
Cerca nella mappa la chiave più piccola k tale che k >= obj . Se tale chiave viene trovata, l'elemento corrispondente viene restituito. Altrimenti, viene restituito null . |
K ceilingKey(K obj) |
Cerca nella mappa la chiave più piccola k tale che k >= obj . Se tale chiave viene trovata, viene restituita. Altrimenti, viene restituito null . |
NavigableSet<K> descendingKeySet() |
Restituisce un NavigableSet che contiene le chiavi nella mappa invocante in ordine inverso. Quindi, restituisce una vista-set inversa delle chiavi. Il set risultante è sostenuto dalla mappa. |
NavigableMap<K,V> descendingMap() |
Restituisce una NavigableMap che è l'inverso della mappa invocante. La mappa risultante è sostenuta dalla mappa invocante. |
Map.Entry<K,V> firstEntry() |
Restituisce il primo elemento nella mappa. Questo è l'elemento con la chiave minore. |
Map.Entry<K,V> floorEntry(K obj) |
Cerca nella mappa la chiave più grande k tale che k <= obj . Se tale chiave viene trovata, l'elemento corrispondente viene restituito. Altrimenti, viene restituito null . |
K floorKey(K obj) |
Cerca nella mappa la chiave più grande k tale che k <= obj . Se tale chiave viene trovata, viene restituita. Altrimenti, viene restituito null . |
NavigableMap<K,V> headMap(K upperBound, boolean incl) |
Restituisce una NavigableMap che include tutte le entrate dalla mappa invocante che hanno chiavi minori di upperBound . Se incl è true , allora un elemento uguale a upperBound è incluso. La mappa risultante è sostenuta dalla mappa invocante. |
Map.Entry<K,V> higherEntry(K obj) |
Cerca nel set la chiave più grande k tale che k > obj . Se tale chiave viene trovata, l'elemento corrispondente viene restituito. Altrimenti, viene restituito null . |
K higherKey(K obj) |
Cerca nel set la chiave più grande k tale che k > obj . Se tale chiave viene trovata, viene restituita. Altrimenti, viene restituito null . |
Map.Entry<K,V> lastEntry() |
Restituisce l'ultimo elemento nella mappa. Questo è l'elemento con la chiave più grande. |
Map.Entry<K,V> lowerEntry(K obj) |
Cerca nel set la chiave più grande k tale che k < obj . Se tale chiave viene trovata, l'elemento corrispondente viene restituito. Altrimenti, viene restituito null . |
K lowerKey(K obj) |
Cerca nel set la chiave più grande k tale che k < obj . Se tale chiave viene trovata, viene restituita. Altrimenti, viene restituito null . |
NavigableSet<K> navigableKeySet() |
Restituisce un NavigableSet che contiene le chiavi nella mappa invocante. Il set risultante è sostenuto dalla mappa invocante. |
Map.Entry<K,V> pollFirstEntry() |
Restituisce il primo elemento, rimuovendo l'elemento nel processo. Poiché la mappa è ordinata, questo è l'elemento con il valore della chiave minore. null viene restituito se la mappa è vuota. |
Map.Entry<K,V> pollLastEntry() |
Restituisce l'ultimo elemento, rimuovendo l'elemento nel processo. Poiché la mappa è ordinata, questo è l'elemento con il valore della chiave maggiore. null viene restituito se la mappa è vuota. |
NavigableMap<K,V> subMap(K lowerBound, boolean lowIncl, K upperBound, boolean highIncl) |
Restituisce una NavigableMap che include tutti gli elementi dalla mappa invocante che hanno chiavi maggiori di lowerBound e minori di upperBound . Se lowIncl è true, allora un elemento uguale a lowerBound è incluso. Se highIncl è true, allora un elemento uguale a upperBound è incluso. La mappa risultante è sostenuta dalla mappa invocante. |
NavigableMap<K,V> tailMap(K lowerBound, boolean incl) |
Restituisce una NavigableMap che include tutti gli elementi dalla mappa invocante che hanno chiavi maggiori di lowerBound . Se incl è true, allora un elemento uguale a lowerBound è incluso. La mappa risultante è sostenuta dalla mappa invocante. |
Diversi metodi lanciano una ClassCastException
quando un oggetto è incompatibile con le chiavi nella mappa. Una NullPointerException
viene lanciata se si tenta di usare un oggetto null
e le chiavi null
non sono consentite nel set. Una IllegalArgumentException
viene lanciata se viene usato un argomento non valido.
L'Interfaccia Map.Entry
L'interfaccia Map.Entry
consente di lavorare con un'entrata della mappa. Ad esempio, ricordiamo che il metodo entrySet()
dichiarato dall'interfaccia Map
restituisce un Set
contenente le entrate della mappa. Ognuno di questi elementi del set è un oggetto Map.Entry
. Map.Entry
è generica ed è dichiarata così:
interface Map.Entry<K, V>
Qui, K
specifica il tipo di chiavi, e V
specifica il tipo di valori. La tabella seguente riassume i metodi non statici dichiarati da Map.Entry
:
Metodo | Descrizione |
---|---|
boolean equals(Object obj) |
Restituisce true se obj è un Map.Entry la cui chiave e valore sono uguali a quelli dell'oggetto invocante. |
K getKey() |
Restituisce la chiave per questo elemento della mappa. |
V getValue() |
Restituisce il valore per questo elemento della mappa. |
int hashCode() |
Restituisce il codice hash per questo elemento della mappa. |
V setValue(V v) |
Imposta il valore per questo elemento della mappa a v . Una ClassCastException viene lanciata se v non è del tipo corretto per la mappa. Una IllegalArgumentException viene lanciata se c'è un problema con v . Una NullPointerException viene lanciata se v è null e la mappa non permette chiavi null . Una UnsupportedOperationException viene lanciata se la mappa non può essere cambiata. |
Map.Entry
ha anche tre metodi statici:
- Il primo è
comparingByKey()
, che restituisce unComparator<Map.Entry<K, V>>
che confronta le entrate per chiave. - Il secondo è
comparingByValue()
, che restituisce unComparator<Map.Entry<K, V>>
che confronta le entrate per valore. - Il terzo è
copyOf()
, aggiunto da JDK 17. Restituisce un oggetto basato su valore non modificabile che è una copia dell'oggetto invocante, ma non fa parte di una mappa.
Le Classi Map
Diverse classi forniscono implementazioni delle interfacce Map
. Le classi che possono essere utilizzate per le mappe sono riassunte qui:
Classe | Descrizione |
---|---|
AbstractMap |
Implementa la maggior parte dell'interfaccia Map . |
EnumMap |
Estende AbstractMap per l'uso con chiavi enum . |
HashMap |
Estende AbstractMap per utilizzare una tabella hash. |
TreeMap |
Estende AbstractMap per utilizzare un albero. |
WeakHashMap |
Estende AbstractMap per utilizzare una tabella hash con chiavi deboli. |
LinkedHashMap |
Estende HashMap per consentire iterazioni nell'ordine di inserimento. |
IdentityHashMap |
Estende AbstractMap e utilizza l'uguaglianza di riferimento quando confronta documenti. |
Notiamo che AbstractMap
è una super-classe per tutte le implementazioni concrete di Map
.
WeakHashMap
implementa una mappa che utilizza "chiavi deboli", che consente a un elemento in una mappa di essere raccolto dal garbage collector quando la sua chiave non è altrimenti utilizzata. Questa classe non viene discussa ulteriormente qui. Le altre classi Map
sono descritte nelle prossime lezioni.