ti-enxame.com

Por que é útil ter valores nulos ou chaves nulas em mapas hash?

Hashtable não permite chaves ou valores nulos, enquanto HashMap permite valores nulos e 1 chave nula.

Questões:

  1. Porque isto é assim?
  2. Como é útil ter essa chave e valores no HashMap?
23
sab

1. Por que isso é assim?

O HashMap é mais recente que o Hashtable e corrige algumas de suas limitações.

Eu só posso adivinhar o que os designers estavam pensando, mas aqui estão meus palpites:

  • A tabela de hash calcula um hash para cada chave chamando hashCode em cada chave. Isso falharia se a chave fosse nula, portanto, isso poderia ser um motivo para não permitir nulos como chaves. 
  • O método Hashtable.get retorna null se a chave não estiver presente. Se null fosse um valor válido, seria ambíguo se nulo significava que a chave estava presente, mas tinha valor nulo ou se a chave estava ausente. A ambiguidade é ruim, portanto, isso pode ser uma razão para não permitir valores nulos como valores.

No entanto, acontece que às vezes você realmente quer armazenar nulos, então as restrições foram removidas no HashMap. O seguinte aviso também foi incluído na documentação de HashMap.get :

Um valor de retorno de nulo não indica necessariamente que o mapa não contém mapeamento para a chave; Também é possível que o mapa mapeie explicitamente a chave para null.


2. Como é útil ter essa chave e valores no HashMap?

É útil armazenar explicitamente null para distinguir entre uma chave que você know existe, mas não possui um valor associado e uma chave que não existe. Um exemplo é uma lista de usuários registrados e seus aniversários. Se você pedir uma data de nascimento de um usuário específico, será possível distinguir entre esse usuário não existente e o usuário existente, mas eles não entraram na data de aniversário.

Eu não consigo pensar em nenhuma (boa) razão para querer armazenar null como uma chave, e em geral eu aconselho contra o uso de null como chave, mas presumivelmente há pelo menos uma pessoa em algum lugar que precisa de chaves que podem ser nulo.

38
Mark Byers

Bem, eu acho que Mark Byers respondeu perfeitamente, então apenas um exemplo simples em que valores e chaves nulos podem ser úteis:

Imagine que você tenha uma função cara que sempre retorna o mesmo resultado para a mesma entrada. Um mapa é uma maneira simples de armazenar seus resultados em cache. Talvez às vezes a função retorne null, mas você precisa salvá-la de qualquer maneira, porque a execução é cara. Portanto, valores nulos devem ser armazenados. O mesmo se aplica à chave nula se for uma entrada aceita para a função.

11
sinuhepop

HashTable é uma classe muito antiga, do JDK 1.0.As classes que estão no lugar de JDK 1.0 são chamadas Legacy classes e, por padrão, são sincronizadas .

Para entender isso, antes de tudo, você precisa entender os comentários escritos nesta classe pelo autor. “Esta classe implementa um hashtable, que mapeia chaves para valores. Qualquer objeto não nulo pode ser usado como uma chave ou como um valor. Para armazenar e recuperar objetos de uma hashtable, os objetos usados ​​como chaves devem implementar o método hashCode e o método equals. ”

A classe HashTable é implementada no mecanismo de hash, significa armazenar qualquer par de valores-chave, seu código de hash necessário do objeto-chave. HashTable calcula um hash para cada chave chamando hashCode em cada chave. Isso falharia Se a chave fosse nula, ela não seria capaz de fornecer o hash para a chave nula, ele lançaria NullPointerException e semelhante é o caso do valor, lançando null se o valor for null .

Mais tarde, porém, percebeu-se que a chave nula e o valor têm sua própria importância, então as implementações revisadas do HashTable foram introduzidas como HashMap, que permitem uma chave nula e vários valores nulos.

Para HashMap, ele permite uma chave nula e há uma verificação nula para chaves, se a chave for nula, esse elemento será armazenado em um local zero na matriz Entry.  

Não podemos ter mais de uma chave Null no HashMap porque As chaves são exclusivas por isso apenas uma chave Null e muitos valores Null são permitidos.

USE- Chave nula que podemos usar para algum valor padrão.

A implementação modificada e melhor do HashTable foi posteriormente introduzida como ConcurrentHashMap .

3
shubham malik

Além do que foi respondido por Mark Bayers, Null é considerado como dados e deve ser armazenado como um valor para verificação adicional. Em muitos casos, valor nulo como valor pode ser usado para verificar se a entrada da chave existe, mas nenhum valor é atribuído a ela, portanto, algumas ações podem ser tomadas de acordo. Isso pode ser feito verificando primeiro se a chave está lá e, em seguida, obtendo o valor. Há mais um caso em que basta colocar os dados que estão chegando (sem qualquer verificação). Todas as verificações são aplicadas a ele depois de obtê-lo.

Considerando nulo como uma chave, acho que pode ser usado para definir alguns dados padrão. Normalmente nulo como chave não faz muito sentido.

2
Amit Agrawal

O Sir HashMap também usa internamente o método hashCode () para inserir um elemento no HashMap, portanto, acho que esse não será o motivo adequado para "por que o HashTable permite a chave nula"

1
user3207104

Isso tornará a interface do Mapa mais fácil de usar/menos detalhada. null é um valor legítimo para tipos de referência. Tornar o mapa capaz de manipular chaves e valores nulos eliminará a necessidade de verificação de nulos antes de chamar a API. Portanto, o mapa api cria menos "surpresas" durante o tempo de execução.

Por exemplo, é comum que o mapa seja usado para categorizar uma coleção de objetos homogêneos com base em um único campo. Quando o mapa é compatível com null, o código será mais conciso, pois é apenas um loop simples, sem qualquer instrução if (é claro que você precisará garantir que a coleção não tenha elementos nulos). Menos linhas de código sem manipulação de ramificações/exceções terão maior probabilidade de serem logicamente corretas.

Por outro lado, não permitir nulo não tornará a interface do mapa melhor/mais segura/fácil de usar. Não é prático confiar no mapa para rejeitar nulos - isso significa que a exceção será lançada e você terá que pegar e lidar com isso. Ou, para se livrar da exceção, você terá que garantir que nada é nulo antes de chamar os métodos do mapa - nesse caso, você não se importa se o mapa aceita null desde que você filtrou a entrada mesmo assim.

0
Xinchao