Complexityeasy0-2 years

A teammate says `ArrayList.add` is O(1), but you've seen it occasionally take much longer than usual. Are they wrong? What's actually happening, and when would it matter in production?

They're not wrong, but "O(1)" here means amortised O(1) — the average over many calls — not a guarantee for any single call. Most add calls are genuinely O(1): there's room, so it's one array write. But when the backing array is full, ArrayList allocates a new array 1.5 times the size and copies every existing element into it, which is O(n) for that one call. Because those resizes get rarer and rarer as the list grows (each one buys 50% more headroom), the total copying work across a million adds stays proportional to a million, not to a million squared — so the average cost per add is constant even though a small number of individual calls are not. It matters in production specifically on a latency-sensitive path: if a request handler appends to an unsized ArrayList and that particular request happens to trigger the resize, that one request pays the O(n) cost in full, and a throughput dashboard averages it away while a P99 latency dashboard does not.

The lesson behind it →