Both, obviously, provide a mapping from a subset of the integers into the integers. There are several differences, but the short answer is that an array is likely to work better for dense keys and a HashMap for sparse keys.
The memory cost per key that you use will be 32 bits for the array, but several times that for the HashMap. The memory cost per key that is in the range but that you don't use is also 32 bits for the array, but can be close to zero for the HashMap.
Array access will be faster than HashMap access.
If you expect to use as many as 50% of the entries, you are much better off with the array. If only odd keys are needed, and the array is large, consider using array index (i-1)/2 to represent the element with key i.
The best way to find which is better for your situation, including finding the density threshold for switching between them, is by testing. This is the procedure I would follow:
- Define an interface for the data structure that has methods for the operations you need to be able to do on it.
- Write your code, except for the actual creation of the structure, in terms only of that interface.
- Define two classes that each implement the interface, one using the array and the other using a HashMap.
- Measure using each of the classes. For the HashMap, you can also experiment with the HashMap constructor arguments.
HashMap<Integer, Integer>, but if there are no gaps this should definitely be aList<Integer>or anint[].