Dalle domande frequenti sulla progettazione dell'API delle raccolte Java :
Perché Map non estende la raccolta?
Questo è stato progettato. Riteniamo che le mappature non siano raccolte e che le raccolte non siano mappature. Pertanto, ha poco senso per Map estendere l'interfaccia Collection (o viceversa).
Se una mappa è una raccolta, quali sono gli elementi? L'unica risposta ragionevole è "coppie chiave-valore", ma ciò fornisce un'astrazione della Mappa molto limitata (e non particolarmente utile). Non puoi chiedere a quale valore viene mappata una determinata chiave, né puoi eliminare la voce per una determinata chiave senza sapere a quale valore è mappata.
La raccolta potrebbe essere fatta per estendere Map, ma questo solleva la domanda: quali sono le chiavi? Non esiste una risposta davvero soddisfacente e forzarne una porta a un'interfaccia innaturale.
Le mappe possono essere visualizzate come raccolte (di chiavi, valori o coppie) e questo fatto si riflette nelle tre "operazioni di visualizzazione della raccolta" su Mappe (keySet, entrySet e valori). Mentre, in linea di principio, è possibile visualizzare un Elenco come Mappa che mappa gli indici sugli elementi, questa ha la cattiva proprietà che l'eliminazione di un elemento dall'Elenco modifica la Chiave associata a ogni elemento prima dell'elemento eliminato. Ecco perché non abbiamo un'operazione di visualizzazione della mappa negli elenchi.
Aggiornamento: penso che la citazione risponda alla maggior parte delle domande. Vale la pena sottolineare che una raccolta di voci non è un'astrazione particolarmente utile. Per esempio:
Set<Map.Entry<String,String>>
consentirebbe:
set.add(entry("hello", "world"));
set.add(entry("hello", "world 2");
(presupponendo un entry()
metodo che crea Map.Entry
un'istanza)
Map
richiedono chiavi univoche quindi ciò violerebbe questo. O se imponi chiavi univoche su una Set
delle voci, non è davvero una Set
in senso generale. È un Set
con ulteriori restrizioni.
Probabilmente si potrebbe dire che la relazione equals()
/ era puramente fondamentale, ma anche questo ha dei problemi. Ancora più importante, aggiunge davvero qualche valore? Potresti scoprire che questa astrazione si interrompe una volta che inizi a guardare i casi angolari.hashCode()
Map.Entry
Vale la pena notare che HashSet
è effettivamente implementato come un HashMap
, non viceversa. Questo è puramente un dettaglio di implementazione ma è comunque interessante.
Il motivo principale per entrySet()
esistere è semplificare l'attraversamento in modo da non dover attraversare le chiavi e quindi cercare una chiave. Non prenderlo come prova prima facie che a Map
dovrebbe essere una Set
delle voci (imho).