The Jon Skeet answer addresses well the two scenarios (map with null value and not null value) in an efficient way.
About the number entries and the efficiency concern, I would like add something.
I have a HashMap with say a 1.000 entries and I am looking at improving the efficiency. If the HashMap is being accessed very frequently, then checking for the key existence at every access will lead to a large overhead.
A map with 1.000 entries is not a huge map.
As well as a map with 5.000 or 10.000 entries.
Map are designed to make fast retrieval with such dimensions.
Now, it assumes that hashCode() of the map keys provides a good distribution.
If you may use an Integer as key type, do it.
Its hashCode() method is very efficient since the collisions are not possible for unique int values :
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; } ... }
If for the key, you have to use another built-in type as String for example that is often used in Map, you may have some collisions but from 1 thousand to some thousands of objects in the Map, you should have very few of it as the String.hashCode() method provides a good distribution.
If you use a custom type, override hashCode() and equals() correctly and ensure overall that hashCode() provides a fair distribution.
You may refer to the item 9 of Java Effective refers it.
Here's a post that details the way.