De las Preguntas frecuentes sobre el diseño de la API de colecciones Java :
¿Por qué Map no extiende la Colección?
Esto fue por diseño. Creemos que las asignaciones no son colecciones y las colecciones no son asignaciones. Por lo tanto, tiene poco sentido que Map extienda la interfaz de Collection (o viceversa).
Si un mapa es una colección, ¿cuáles son los elementos? La única respuesta razonable es "pares clave-valor", pero esto proporciona una abstracción de mapa muy limitada (y no particularmente útil). No puede preguntar a qué valor se asigna una clave determinada, ni puede eliminar la entrada de una clave determinada sin saber a qué valor se asigna.
Se podría hacer una colección para extender el Mapa, pero esto plantea la pregunta: ¿cuáles son las claves? No hay una respuesta realmente satisfactoria, y forzar una lleva a una interfaz no natural.
Los mapas se pueden ver como Colecciones (de claves, valores o pares), y este hecho se refleja en las tres "Operaciones de vista de Colección" en Mapas (keySet, entrySet y valores). Si bien, en principio, es posible ver una Lista como un Mapa que asigna índices a elementos, esto tiene la desagradable propiedad de que eliminar un elemento de la Lista cambia la Clave asociada con cada elemento antes del elemento eliminado. Es por eso que no tenemos una operación de vista de mapa en Listas.
Actualización: creo que la cita responde a la mayoría de las preguntas. Vale la pena enfatizar la parte acerca de que una colección de entradas no es una abstracción particularmente útil. Por ejemplo:
Set<Map.Entry<String,String>>
permitiría:
set.add(entry("hello", "world"));
set.add(entry("hello", "world 2");
(suponiendo un entry()
método que crea una Map.Entry
instancia)
Map
s requieren claves únicas, por lo que esto violaría esto. O si impone claves únicas en una Set
de las entradas, no es realmente una Set
en el sentido general. Es una Set
con más restricciones.
Podría decirse que la relación equals()
/ hashCode()
para Map.Entry
fue puramente clave, pero incluso eso tiene problemas. Más importante aún, ¿realmente agrega algún valor? Es posible que esta abstracción se descomponga una vez que comience a mirar los casos de esquina.
Vale la pena señalar que el HashSet
realmente se implementa como un HashMap
, no al revés. Esto es puramente un detalle de implementación, pero no obstante es interesante.
La razón principal para entrySet()
existir es simplificar el recorrido para que no tenga que atravesar las teclas y luego hacer una búsqueda de la clave. No lo tome como evidencia prima facie de que a Map
debería ser una Set
de entradas (en mi humilde opinión).