Language Implementations

Sorting Algorithms in Java

Implement classic sorting algorithms in Java with code examples, and learn how Arrays.sort() uses Tim Sort for objects and Dual-Pivot Quick Sort for primitives.

Aman Jaiman
10 min read
On this page +
  1. In plain English
  2. The built-in sorts
  3. Why two algorithms?
  4. Quick Sort in Java
  5. What algorithm does Java actually use?
  6. Frequently asked questions

Java's standard library has one of the most carefully engineered sorting setups of any language — it uses different algorithms depending on whether you sort objects or primitives. This guide covers both the built-ins and clean implementations of the core algorithms.

The built-in sorts #

Arrays.sort(Object[]) and Collections.sort() use Tim Sort (stable). Arrays.sort(int[]) and other primitive overloads use Dual-Pivot Quick Sort, which is faster for primitives where stability is irrelevant. Use a Comparator for custom orderings.

Why two algorithms? #

Objects need stability for correct multi-key sorting, so Java uses stable Tim Sort. Primitives have no identity beyond their value, so stability is meaningless — and Dual-Pivot Quick Sort partitions around two pivots for excellent cache performance. See what algorithm Java uses for the details.

Quick Sort in Java #

void quickSort(int[] a, int lo, int hi) {
    if (lo < hi) {
        int p = partition(a, lo, hi);
        quickSort(a, lo, p - 1);
        quickSort(a, p + 1, hi);
    }
}

What algorithm does Java actually use? #

Java is the clearest example of a standard library deliberately using two different sorting algorithms and choosing between them based on what you are sorting. Which one you get depends entirely on whether you pass objects or primitives.

Objects — Arrays.sort(Object[]) and Collections.sort() — use Tim Sort. Since Java 7 this has been a port of the same adaptive Merge Sort hybrid that Python uses. It is stable, which is essential for objects: if you sort a list of employees by name and then by department, stability is what keeps each department's employees alphabetical. It costs O(n) auxiliary memory, which is considered an acceptable price for objects since you are already paying for references and heap allocation.

Primitives — Arrays.sort(int[]) and friends — use dual-pivot Quick Sort. Contributed by Vladimir Yaroslavskiy in Java 7, this partitions around two pivots into three regions rather than one pivot into two. That produces shallower recursion and better cache behaviour than classic Quick Sort, and it measurably outperformed the previous implementation.

Why the split? Because stability is meaningless for primitives. Two int values of 42 are indistinguishable, so there is no original order worth preserving — which means Java can take the faster, unstable, in-place algorithm and lose nothing at all. For objects, where two "equal" items can differ in every other field, stability is worth the memory.

Modern JDKs have hardened the primitive path further: it uses Insertion Sort below a small threshold, and newer versions detect pathological input and fall back to Heap Sort so that the worst case cannot degrade to O(n²).

Found this useful?

Share it with someone who is learning this too.

Questions

Frequently asked questions

What sorting algorithm does Java use? +
Java uses Tim Sort for object arrays (Arrays.sort(Object[]), Collections.sort) because it is stable, and Dual-Pivot Quick Sort for primitive arrays (int[], double[]) because it is faster where stability does not matter.
Why does Java use different sorts for primitives and objects? +
Objects require stable sorting for multi-key ordering, so Java uses Tim Sort. Primitives have no identity beyond value, so the faster, unstable Dual-Pivot Quick Sort is used.
What sorting algorithm does Java use? +
Two different ones, chosen by type. Arrays.sort() on an object array and Collections.sort() use Tim Sort, a stable adaptive Merge Sort hybrid. Arrays.sort() on a primitive array uses dual-pivot Quick Sort, which is faster and in-place but unstable. The split is deliberate: stability matters for objects and is meaningless for primitives.
What is dual-pivot Quick Sort? +
A Quick Sort variant that partitions around two pivots instead of one, splitting the array into three regions per pass — less than the smaller pivot, between the two, and greater than the larger. The extra partition means fewer recursive levels and better cache locality than classic single-pivot Quick Sort. Vladimir Yaroslavskiy's implementation replaced Java's previous primitive sort in Java 7 after benchmarking faster on real workloads.

See it in motion

Watch this algorithm and nine others run step by step, with live pseudocode and comparison counters.

Launch the visualiser
Aman Jaiman
Written by
Aman Jaiman

Software engineer at a stealth-stage startup, and previously a front-end engineer for around a year and a half.

Keep reading

Related guides

Link copied