Generally it's the other way around - once you factor in the per-instance object overhead, array-backed storage tends to win. Unless the ArrayLists are sparsely populated, of course.
They are - each bucket is an array list, which means that we currently allocate ~(Ch * Ca) pointers for each HashMap instance, where Ch is the capacity of the HashMap and Ca is the default capacity of ArrayList. Using linked lists, we can reduce it to ~Ch with no performance impact.
