A resposta de Jon Skeet aborda bem os dois cenários (mapa com nullvalor e não nullvalor) de maneira eficiente.
Sobre as entradas de número e a preocupação com eficiência, gostaria de acrescentar algo.
Eu tenho um HashMap com 1.000 entradas e estou procurando melhorar a eficiência. Se o HashMap estiver sendo acessado com muita frequência, verificar a existência da chave em todos os acessos resultará em uma grande sobrecarga.
Um mapa com 1.000 entradas não é um mapa enorme.
Bem como um mapa com 5.000 ou 10.000 entradas.
Mapsão projetados para fazer uma recuperação rápida com essas dimensões.
Agora, assume que hashCode()as chaves do mapa fornecem uma boa distribuição.
Se você pode usar um Integertipo de chave, faça-o.
Seu hashCode()método é muito eficiente, pois as colisões não são possíveis para intvalores únicos :
public final class Integer extends Number implements Comparable<Integer> {
...
@Override
public int hashCode() {
return Integer.hashCode(value);
}
public static int hashCode(int value) {
return value;
}
...
}
Se, para a chave, você precisar usar outro tipo interno, como Stringpor exemplo, frequentemente usado Map, poderá haver algumas colisões, mas de mil a alguns milhares de objetos no Map, você deve ter muito poucos como String.hashCode()método fornece uma boa distribuição.
Se você usar um tipo personalizado, substitua hashCode()e equals()corrija e garanta que, no geral, hashCode()forneça uma distribuição justa.
Você pode consultar o item 9 do Java Effectivereferente.
Aqui está um post que detalha o caminho.