"Talvez o problema não seja que nada esteja nos incomodando, mas que estamos incomodando."
bmargulies
3
Em Guava, coleções do Google, muitas classes não permitem null e o raciocínio por trás disso é que 95% dos casos não precisam de null e podem representar bugs, potencialmente difíceis de encontrar.
stivlo
O estranho é que ConcurrentHashMapnão suporta chaves nulas, mas HashMapsim.
codepleb
2
Apenas o HashMap permite null :)
subhashis
Respostas:
126
Não tenho certeza do que você está perguntando, mas se você está procurando um exemplo de quando alguém gostaria de usar uma chave nula, eu as uso frequentemente em mapas para representar o caso padrão (ou seja, o valor que deve ser usado se uma determinada chave não estiver presente):
Map<A, B> foo;
A search;
B val = foo.containsKey(search)? foo.get(search): foo.get(null);
HashMaplida com chaves nulas especialmente (uma vez que não pode chamar .hashCode()um objeto nulo), mas os valores nulos não são nada de especial, eles são armazenados no mapa como qualquer outra coisa
Portanto, se .hashCode () não for possível em null, quem decide em qual carro a chave nula entrará?
Pacerier
26
@Pacerier Existe um método especial em HashMap( putForNullKey) que trata disso; ele o armazena na tabela 0
Michael Mrozek
1
@MichaelMrozek sua última linha B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);, acho que podemos simplesmente chamar o método get na chave de pesquisa que terá o mesmo resultado. B val = foo.get(search);você poderia me corrigir se eu estou entendendo algo errado?
dheerajraaj
6
@ dheeraj92 Seu código será definido valcomo nullse a chave não existir; o meu define para qualquer nullmapa no mapa. Esse era o ponto, eu armazenei um valor não nulo padrão na nullchave do mapa e o utilizo se a chave real não existir
Michael Mrozek
28
Um exemplo seria modelar árvores. Se você estiver usando um HashMap para representar uma estrutura de árvore, onde a chave é o pai e o valor é a lista de filhos, então os valores da nullchave seriam os nós raiz.
Um exemplo de uso de nullvalores é ao usar um HashMapcomo cache para resultados de uma operação cara (como uma chamada para um serviço da web externo) que pode retornar null.
Colocar um nullvalor no mapa permite distinguir entre o caso em que a operação não foi realizada para uma determinada chave ( cache.containsKey(someKey)retorna false) e onde a operação foi realizada, mas retornou um nullvalor ( cache.containsKey(someKey)retorna true, cache.get(someKey)retorna null).
Sem nullvalores, você teria que colocar algum valor especial no cache para indicar uma nullresposta ou simplesmente não armazenar em cache essa resposta e executar a operação todas as vezes.
As respostas até agora consideram apenas o valor de ter uma nullchave, mas a pergunta também pergunta sobre any number of null values.
O benefício de armazenar o valor em nullrelação a uma chave em um HashMap é o mesmo que em bancos de dados, etc - você pode registrar uma distinção entre ter um valor que está vazio (por exemplo, string "") e não ter nenhum valor (nulo) .
Aqui está meu único exemplo um tanto artificial de um caso em que a nullchave pode ser útil:
publicclassTimer{privatestaticfinalLogger LOG =Logger.getLogger(Timer.class);privatestaticfinalMap<String,Long> START_TIMES =newHashMap<String,Long>();publicstaticsynchronizedvoid start(){long now =System.currentTimeMillis();if(START_TIMES.containsKey(null)){
LOG.warn("Anonymous timer was started twice without being stopped; previous timer has run for "+(now - START_TIMES.get(null).longValue())+"ms");}
START_TIMES.put(null, now);}publicstaticsynchronizedlong stop(){if(! START_TIMES.containsKey(null)){return0;}return printTimer("Anonymous", START_TIMES.remove(null),System.currentTimeMillis());}publicstaticsynchronizedvoid start(String name){long now =System.currentTimeMillis();if(START_TIMES.containsKey(name)){
LOG.warn(name +" timer was started twice without being stopped; previous timer has run for "+(now - START_TIMES.get(name).longValue())+"ms");}
START_TIMES.put(name, now);}publicstaticsynchronizedlong stop(String name){if(! START_TIMES.containsKey(name)){return0;}return printTimer(name, START_TIMES.remove(name),System.currentTimeMillis());}privatestaticlong printTimer(String name,long start,long end){
LOG.info(name +" timer ran for "+(end - start)+"ms");return end - start;}}
Se você está tentando parar um cronômetro inexistente ou que já foi interrompido, isso deve ser um erro, não ignorado.
Processo judicial de Monica
@QPaysTaxes - Depende de sua intenção. Se você quer um utilitário leve que possa ser usado facilmente, geralmente não quer ficar por throw Exceptionperto. Além disso, tentar parar um cronômetro inexistente ou já parado é algo do qual o chamador geralmente pode se recuperar.
aroth
1
Outro exemplo: eu o utilizo para agrupar dados por data. Mas alguns dados não têm data. Posso agrupá-lo com o cabeçalho "NoDate"
ConcurrentHashMap
não suporta chaves nulas, masHashMap
sim.Respostas:
Não tenho certeza do que você está perguntando, mas se você está procurando um exemplo de quando alguém gostaria de usar uma chave nula, eu as uso frequentemente em mapas para representar o caso padrão (ou seja, o valor que deve ser usado se uma determinada chave não estiver presente):
HashMap
lida com chaves nulas especialmente (uma vez que não pode chamar.hashCode()
um objeto nulo), mas os valores nulos não são nada de especial, eles são armazenados no mapa como qualquer outra coisafonte
HashMap
(putForNullKey
) que trata disso; ele o armazena na tabela 0B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);
, acho que podemos simplesmente chamar o método get na chave de pesquisa que terá o mesmo resultado.B val = foo.get(search);
você poderia me corrigir se eu estou entendendo algo errado?val
comonull
se a chave não existir; o meu define para qualquernull
mapa no mapa. Esse era o ponto, eu armazenei um valor não nulo padrão nanull
chave do mapa e o utilizo se a chave real não existirUm exemplo seria modelar árvores. Se você estiver usando um HashMap para representar uma estrutura de árvore, onde a chave é o pai e o valor é a lista de filhos, então os valores da
null
chave seriam os nós raiz.fonte
Um exemplo de uso de
null
valores é ao usar umHashMap
como cache para resultados de uma operação cara (como uma chamada para um serviço da web externo) que pode retornarnull
.Colocar um
null
valor no mapa permite distinguir entre o caso em que a operação não foi realizada para uma determinada chave (cache.containsKey(someKey)
retornafalse
) e onde a operação foi realizada, mas retornou umnull
valor (cache.containsKey(someKey)
retornatrue
,cache.get(someKey)
retornanull
).Sem
null
valores, você teria que colocar algum valor especial no cache para indicar umanull
resposta ou simplesmente não armazenar em cache essa resposta e executar a operação todas as vezes.fonte
As respostas até agora consideram apenas o valor de ter uma
null
chave, mas a pergunta também pergunta sobreany number of null values
.O benefício de armazenar o valor em
null
relação a uma chave em um HashMap é o mesmo que em bancos de dados, etc - você pode registrar uma distinção entre ter um valor que está vazio (por exemplo, string "") e não ter nenhum valor (nulo) .fonte
Aqui está meu único exemplo um tanto artificial de um caso em que a
null
chave pode ser útil:fonte
throw Exception
perto. Além disso, tentar parar um cronômetro inexistente ou já parado é algo do qual o chamador geralmente pode se recuperar.Outro exemplo: eu o utilizo para agrupar dados por data. Mas alguns dados não têm data. Posso agrupá-lo com o cabeçalho "NoDate"
fonte
Uma chave nula também pode ser útil quando o mapa armazena dados para seleções de IU em que a chave do mapa representa um campo de bean.
Um valor de campo nulo correspondente seria, por exemplo, representado como "(selecione)" na seleção da IU.
fonte