W3docs

Sorting Arrays in Java

Sort Java arrays of primitives and objects using Arrays.sort, with custom comparators for objects.

Sorting is one of those operations you'll reach for constantly, and Java's standard library makes it a one-liner — most of the time. The wrinkle is that the kind of element matters: primitives sort one way, objects another, and "I want descending order" or "sort by a field" calls for a Comparator. This chapter walks through all of it.

The core method is Arrays.sort. It sorts in place — it mutates the array you pass in. If you want to keep the original, copy it first.

Sorting primitives

For int[], long[], double[], char[], etc., one call is all you need:

import java.util.Arrays;

int[] data = {3, 1, 4, 1, 5, 9, 2, 6};
Arrays.sort(data);
System.out.println(Arrays.toString(data));   // [1, 1, 2, 3, 4, 5, 6, 9]

Primitive sort is always ascending. There is no Comparator overload — primitives can't be compared by an arbitrary function the way objects can.

To sort descending, the trick is to box to Integer[] and supply a comparator, or sort ascending and reverse manually:

int[] data = {3, 1, 4};
Arrays.sort(data);
// reverse in place
for (int i = 0, j = data.length - 1; i < j; i++, j--) {
  int tmp = data[i]; data[i] = data[j]; data[j] = tmp;
}

Sorting a range

Pass from (inclusive) and to (exclusive) to sort only part of the array:

int[] data = {9, 8, 7, 6, 5, 4, 3, 2, 1};
Arrays.sort(data, 2, 6);
// {9, 8, 4, 5, 6, 7, 3, 2, 1} — only positions 2..5 sorted

The elements outside the range stay put.

Sorting object arrays (natural order)

For an array of objects whose class implements Comparable<T>String, the boxed numeric wrappers, LocalDate, anything with a "natural" order — call Arrays.sort directly:

String[] words = {"banana", "apple", "cherry"};
Arrays.sort(words);
// {"apple", "banana", "cherry"} — alphabetical

If the class doesn't implement Comparable, this throws ClassCastException at runtime. The fix is to supply a Comparator.

Sorting with a Comparator

A Comparator<T> is a function that, given two Ts, returns a negative number, zero, or a positive number to say "first is smaller", "equal", "first is larger." The cleanest way to build one is with Comparator.comparing:

record Player(String name, int score) {}

Player[] players = {
  new Player("Ada", 1500),
  new Player("Linus", 1800),
  new Player("Grace", 1650)
};

// sort by score, ascending
Arrays.sort(players, Comparator.comparing(Player::score));

// sort by score, descending
Arrays.sort(players, Comparator.comparing(Player::score).reversed());

// sort by name (case-insensitive), then by score as tiebreaker
Arrays.sort(players,
  Comparator.comparing(Player::name, String.CASE_INSENSITIVE_ORDER)
            .thenComparing(Player::score));

The Comparator.comparing(...).reversed() and .thenComparing(...) chain is the idiomatic way to compose sort orders. You almost never need to write a comparator class by hand.

Sorting boxed primitives

Integer[], Double[], etc. are object arrays — so all the Comparator machinery is available:

Integer[] nums = {3, 1, 4, 1, 5};
Arrays.sort(nums, Comparator.reverseOrder());
// {5, 4, 3, 1, 1}

If you need descending order for a primitive array, boxing is the cleanest route — assuming the array isn't huge, the cost is acceptable.

Stability

Sort stability means equal elements keep their original relative order. Java's object sort is stable: if two Players have the same score, the one that came first stays first. Primitive sort is not guaranteed stable, but since primitives carry no identity beyond their value, you can't tell.

This matters when you chain sorts — e.g., sort by score, then by name. With a stable sort, the second pass preserves the first ordering wherever the new key ties. With thenComparing, you compose both keys into one comparator and side-step the question, which is usually the cleaner approach.

parallelSort

For very large arrays, Arrays.parallelSort distributes the work across multiple threads:

int[] huge = new int[10_000_000];
// ... fill huge ...
Arrays.parallelSort(huge);

Same API, same in-place semantics. There's overhead in setting up the threads, so for small arrays a plain sort is faster. The crossover is around tens of thousands of elements; below that, don't bother.

A worked example

java— editable, runs on the server

What's next

You've now seen the read-and-transform side of arrays. The last chapter of this part covers copying arrays — the right way to duplicate, slice, and resize an existing array without entangling the two with shared references.

Practice

Practice

How do you sort an int[] in descending order?