Take n random elements from a ListE?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Selecting n random elements from a Java List<E> sounds simple, but the correct solution depends on whether duplicates are allowed and whether the original list may be reordered. In most business code, the usual requirement is sampling without replacement, which means the same element should not appear twice in the result. A good implementation should also validate n and make the randomness strategy explicit.
Clarify the Sampling Rule First
There are two common interpretations:
- sample without replacement, where each chosen element is unique
- sample with replacement, where the same element may be chosen multiple times
Most developers mean the first one. If you do not define this up front, the code can look correct while returning the wrong type of random sample.
Simple Approach: Shuffle a Copy
For moderate list sizes, the easiest solution is to copy the list, shuffle it, and take the first n items.
This is readable and usually the best default when the list comfortably fits in memory.
Sampling With Replacement
If duplicates are allowed, choose random indices independently.
Here duplicates are expected behavior, not a bug.
Do Not Shuffle the Original List Unless That Is Intentional
Calling Collections.shuffle(source) changes the list in place. That may be acceptable for local temporary lists, but it is risky when other code still depends on the original order.
Unsafe for shared state:
Safer default:
Mutation should be a conscious choice, not an accidental side effect.
Large Inputs: Consider Reservoir Sampling
If the input is very large or arrives as a stream, shuffling the full dataset may be wasteful. Reservoir sampling gives a uniform sample of n elements in one pass.
This matters when the list is huge or when the data source is effectively streaming.
Reproducibility for Tests
If you need deterministic behavior in tests, do not hard-code the global random source. Accept a Random instance or seed it deliberately.
That makes unit tests stable and easier to debug.
Common Pitfalls
The biggest mistake is not defining whether duplicates are allowed. Sampling with replacement and without replacement solve different problems.
Another issue is shuffling the original list in place and surprising the rest of the program.
Developers also sometimes ignore invalid values of n. A negative sample size or a request larger than the list should fail clearly rather than produce ambiguous behavior.
Summary
- Decide first whether sampling should allow duplicates.
- For most lists, shuffle a copy and take the first
nelements. - Use random-index selection only when sampling with replacement is intended.
- Avoid mutating the original list unless reordering it is acceptable.
- For huge inputs, reservoir sampling is a better fit than full-list shuffling.

