Java Language Collections and Primitive Values


Collections in Java only work for objects. I.e. there is no Map<int, int> in Java. Instead, primitive values need to be boxed into objects, as in Map<Integer, Integer>. Java auto-boxing will enable transparent use of these collections:

Map<Integer, Integer> map = new HashMap<>();
map.put(1, 17); // Automatic boxing of int to Integer objects
int a = map.get(1); // Automatic unboxing.

Unfortunately, the overhead of this is substantial. A HashMap<Integer, Integer> will require about 72 bytes per entry (e.g. on 64-bit JVM with compressed pointers, and assuming integers larger than 256, and assuming 50% load of the map). Because the actual data is only 8 bytes, this yields a massive overhead. Furthermore, it requires two level of indirection (Map -> Entry -> Value) it is unnecessarily slow.

There exist several libraries with optimized collections for primitive data types (that require only ~16 bytes per entry at 50% load, i.e. 4x less memory, and one level of indirection less), that can yield substantial performance benefits when using large collections of primitive values in Java.