Did some searching before asking, some not-so-reliable sources suggest that there's an underlying Object[] array.
Is it as simple as that? i.e. it handles resizing when necessary, maybe does a few tricks like doubling the size to get better amortized runtimes, and keeps track of where the first empty slot in the array is.
Or, are there optimizations done for membership testing and sparse arrays?
ArrayList, not advice when using one. Additionally,ArrayListdocumentation enforces that the capacity of anArrayListbe managed such thatArrayList::addhas amortized constant time. IfArrayList::addresized the underlying memory each time it was called, it would haven^2complexity. Something as simple as doubling capacity each time more space is needed guarantees amortized constant time. It'll do many fewer changes to capacity than increasing it by one each call toArrayList::add.