How to choose a data structure

Start from the operations your code performs most, not from the structure you like.

Choosing well is a mechanical process, not taste. Answer four questions about your problem and the field narrows to one or two candidates.

1. What do you do most often?

Count the operations in the hot path: lookup by key, lookup by position, insert at the end, insert in the middle, delete, iterate in order, find the smallest.

2. Does order matter?

Insertion order, sorted order, or no order at all? Sorted order is expensive to maintain — do not pay for it unless you read it.

3. How large does it get?

At ten elements everything is fast and readability wins. At ten million, the difference between O(n) and O(log n) is the difference between a request and a timeout.

4. Do you need the values, or just membership?

Membership alone means a set. Keys with values means a map.

The cheat sheet

You need Reach for Why
Access by index Array O(1) by position, contiguous memory
Lookup by key Hash map O(1) average
Membership only Set O(1) average, no value stored
First in, first out Queue O(1) at both ends
Last in, first out Stack O(1) push and pop
Always the smallest or largest Heap O(log n) insert, O(1) peek
Sorted iteration plus fast lookup Balanced BST O(log n) both, ordered traversal
Prefix matching on strings Trie O(length of key)

Worked example

"Given a stream of events, report the 10 most recent per user."

Most frequent operation: append per user, read the last ten. Order matters, and it is recency. Keys are user ids.

That is a hash map from user id to a fixed-size queue — not an array of every event that you filter and sort on each read. The filter-and-sort version is O(n log n) per read and gets slower every day the system stays up.