Common algorithms: sort, binarySearch, reverse, shuffle,… — Cracked Java
// Java Collections Framework · Collections Utility Class
JuniorTheory

Common algorithms: sort, binarySearch, reverse, shuffle, rotate, frequency, disjoint.

The Collections class ships a handful of fundamental algorithms that operate on List (mostly). Most are O(n) in-place mutations; sort and binarySearch are O(n log n) / O(log n). Worth knowing because they're often the shortest, clearest way to express common operations.

sort

List<Integer> xs = new ArrayList<>(List.of(3, 1, 4, 1, 5, 9, 2, 6));
Collections.sort(xs);                                // natural order
Collections.sort(xs, Comparator.reverseOrder());     // custom comparator

Uses TimSort under the hood — adaptive merge sort that's O(n log n) worst case and O(n) on already-sorted or nearly-sorted input. Stable. In Java 8+ you can also do list.sort(comparator) directly on the list.

binarySearch

List<Integer> sorted = List.of(1, 3, 5, 7, 9);
int idx = Collections.binarySearch(sorted, 5);     // returns 2
int miss = Collections.binarySearch(sorted, 4);    // returns -(insertion point) - 1
                                                    // here: -3 (would insert at idx 2)

O(log n) on RandomAccess lists (ArrayList), O(n) on linked lists due to traversal. Input must be sorted by the same comparator (or natural order) you pass — undefined behavior otherwise. The negative return on miss is -(insertionPoint) - 1 so you can compute insertion point as -result - 1.

reverse

List<String> xs = new ArrayList<>(List.of("a", "b", "c", "d"));
Collections.reverse(xs);   // [d, c, b, a]

In-place, O(n). For an immutable reversed view, use Sequenced Collections (Java 21+): list.reversed().

shuffle

Collections.shuffle(xs);                     // uses ThreadLocalRandom
Collections.shuffle(xs, new Random(42));     // reproducible with seed

Fisher-Yates, O(n). For tests, always pass a seeded Random so failures are reproducible.

rotate

List<Integer> xs = new ArrayList<>(List.of(1, 2, 3, 4, 5));
Collections.rotate(xs, 2);   // [4, 5, 1, 2, 3]  — shifts right by 2
Collections.rotate(xs, -1);  // shifts left by 1

In-place, O(n). Useful for circular buffers and "everyone passes their cards left" simulations.

frequency

List<String> words = List.of("a", "b", "a", "c", "a", "b");
int count = Collections.frequency(words, "a");   // 3

O(n) linear count. Equivalent to streams (stream.filter(x::equals).count()) but more concise. Uses equals, handles null.

disjoint

boolean noOverlap = Collections.disjoint(
    List.of(1, 2, 3),
    Set.of(4, 5, 6)
);   // true

true iff the two collections share no element. Smart enough to iterate the smaller collection and look up in the larger — pass a Set as one argument for O(n) total instead of O(n*m).

Quick reference

OperationBestAverageWorstNote
sortO(n)O(n log n)O(n log n)TimSort, stable
binarySearch (RandomAccess)O(1)O(log n)O(log n)requires sorted
reverse / rotateO(n)O(n)O(n)in-place
shuffleO(n)O(n)O(n)Fisher-Yates
frequencyO(n)O(n)O(n)linear scan
disjointO(1)O(n)O(n*m)depends on input types

Mark your status