Sorting becomes a product decision when some values are missing. Should an incomplete record appear first so someone can correct it, or last so completed records remain easy to browse? The answer should be deliberate.
Java’s comparator utilities make that decision expressible in code. The important part is applying the null policy at the correct level and checking how it interacts with ascending or descending order.
Define the desired result first
Suppose an application displays appointment names, with a few entries still unnamed. A simple requirement might be: sort the available names alphabetically and place missing names at the end.
For a list of nullable strings, that policy can be represented as:
Comparator<String> nameOrder =
Comparator.nullsLast(Comparator.naturalOrder());
The Comparator documentation states that nullsLast considers null greater than non-null values and delegates comparisons between non-null values to the supplied comparator. Two null values compare as equal.
The code now records a visible policy. A reviewer does not need to infer the intended placement from scattered conditional statements.
Reverse the part you mean to reverse
Descending order introduces a subtle choice. Consider these expressions:
Comparator<String> first =
Comparator.nullsLast(Comparator.<String>naturalOrder())
.reversed();
Comparator<String> second =
Comparator.nullsLast(Comparator.reverseOrder());
The first reverses the entire comparison, including the placement of nulls. The second reverses the ordering of non-null values while retaining the outer nulls-last policy.
For an illustrative list containing “Cedar”, “Maple”, and null, the second expression puts “Maple” before “Cedar” and leaves the missing value last.
Write down the expected sequence before choosing the expression. That small step prevents a user-interface requirement from being lost in a fluent chain of method calls.
Separate missing records from missing fields
A null object and an object containing a null field are different cases.
For records with an optional name, a comparator can apply the policy to the extracted field:
Comparator<Customer> order =
Comparator.comparing(
Customer::name,
Comparator.nullsLast(Comparator.naturalOrder())
);
This assumes that the Customer objects themselves are non-null. If the collection may also contain null customers, the outer comparator needs a separate policy.
Keeping those assumptions explicit helps the team decide where invalid data should be rejected and where incomplete data is acceptable.
Test the order as a complete sequence
A useful test contains ordinary values, at least one null, and duplicate values. Assert the full expected order rather than checking only that sorting did not throw an exception.
If equal names need a predictable secondary order, add a meaningful tie-breaker such as a unique identifier. Choose it according to the display requirement.
Also remember that sorting a list with the standard collection sorting utilities requires a list that supports the necessary modifications. Java documents stable sorting for Collections.sort, preserving the relative order of elements that compare as equal.
Finally, review how the interface labels missing values. Placing them correctly is only half the task; readers should also understand whether the blank means unknown, not supplied, or not applicable.

