Nas Perguntas frequentes sobre o design da API Java Collections :
Por que o Map não estende a coleção?
Isso foi por design. Achamos que os mapeamentos não são coleções e coleções não são mapeamentos. Portanto, faz pouco sentido para o Map estender a interface Collection (ou vice-versa).
Se um mapa é uma coleção, quais são os elementos? A única resposta razoável é "Pares de valor-chave", mas isso fornece uma abstração de mapa muito limitada (e não particularmente útil). Você não pode perguntar para qual valor uma determinada chave é mapeada nem excluir a entrada de uma determinada chave sem saber para qual valor ela é mapeada.
Pode-se fazer uma coleta para estender o Mapa, mas isso levanta a questão: quais são as chaves? Não existe uma resposta realmente satisfatória, e forçar um leva a uma interface não natural.
Os mapas podem ser visualizados como coleções (de chaves, valores ou pares), e esse fato é refletido nas três "operações de exibição de coleção" nos mapas (keySet, entrySet e valores). Embora seja, em princípio, possível visualizar uma Lista como um mapa, mapeando índices para elementos, isso tem a propriedade desagradável de que excluir um elemento da Lista altera a Chave associada a todos os elementos antes do elemento excluído. É por isso que não temos uma operação de visualização de mapa nas Listas.
Atualização: acho que a citação responde à maioria das perguntas. Vale ressaltar que a parte de uma coleção de entradas não é uma abstração particularmente útil. Por exemplo:
Set<Map.Entry<String,String>>
permitiria:
set.add(entry("hello", "world"));
set.add(entry("hello", "world 2");
(assumindo um entry()
método que cria uma Map.Entry
instância)
Map
s exigem chaves exclusivas, portanto isso violaria isso. Ou se você impõe chaves exclusivas em uma Set
das entradas, não é realmente uma Set
no sentido geral. É um Set
com mais restrições.
Indiscutivelmente, você poderia dizer que o relacionamento equals()
/ estava puramente essencial, mas mesmo isso tem problemas. Mais importante, isso realmente agrega algum valor? Você pode achar que essa abstração é interrompida quando você começa a examinar os casos de canto.hashCode()
Map.Entry
Vale a pena notar que o HashSet
é realmente implementado como um HashMap
, e não o contrário. Isso é puramente um detalhe de implementação, mas é interessante, no entanto.
A principal razão de entrySet()
existir é simplificar a travessia para que você não precise atravessar as teclas e, em seguida, faça uma busca na chave. Não tome isso como evidência prima facie de que a Map
deve ser uma Set
das entradas (imho).