A list containing null elements is sorted with a null-tolerant comparator. What does this print?
```java
import java.util.*;
public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>(Arrays.asList("bob", null, "amy", null, "cara"));
names.sort(Comparator.nullsLast(Comparator.comparing(String::length)));
System.out.println(names);
}
}
```
A. Throws NullPointerException
That is what happens without the nullsLast wrapper; nullsLast handles the null cases itself and only delegates when both arguments are non-null, so the length extractor is never applied to a null and no NPE occurs.
B. [null, null, bob, amy, cara]
That is nullsFirst output; it encodes the belief that the wrapper name describes where the nulls come from rather than where they end up — nullsLast sinks them to the end.
C. [amy, bob, cara, null, null]
Assumes a comparator on length breaks ties alphabetically; a comparator that returns 0 leaves the order to the sort, and List.sort is stable, so bob (input first) stays ahead of amy.
D. [bob, amy, cara, null, null]Correct answer
Correct: nullsLast sends the nulls to the end, and among the non-nulls comparing by length orders bob(3), amy(3), cara(4) with the stable sort keeping bob before amy on the length-3 tie.
Explanation
Trace: nullsLast(cmp) returns a comparator that handles the null cases itself — null is greater than any non-null, two nulls are equal — and only delegates to the wrapped comparator when *both* arguments are non-null. So String::length is never applied to a null. Among the non-nulls, comparing(String::length) gives bob=3, amy=3, cara=4, and List.sort is a stable sort: bob and amy tie on length 3 and therefore keep their input order (bob came first). The nulls sink to the end, and the run prints `[bob, amy, cara, null, null]`.
Why the others are wrong:
`[null, null, bob, amy, cara]` is what nullsFirst produces — the same list sorted with Comparator.nullsFirst(...) really does print that. It encodes the belief that the wrapper name describes where the nulls *come from* rather than where they end up.
`[amy, bob, cara, null, null]` assumes that a comparator on length breaks its ties alphabetically. It does not: a comparator that returns 0 leaves the order to the sort, and a stable sort preserves the encounter order, so bob stays ahead of amy.
`Throws NullPointerException` is what you get if you drop the nullsLast wrapper — `names.sort(Comparator.comparing(String::length))` on this list really does throw NPE when the key extractor is handed a null. That is exactly the failure nullsLast exists to prevent.
Exam tip: Comparator.nullsFirst/nullsLast is the only sanctioned way to sort a collection containing nulls; the key-extractor comparators (comparing, comparingInt) call the extractor on every element and will NPE. And remember that List.sort/Collections.sort are contractually *stable*, so tied elements never get shuffled — which is why the tie-break here is "input order", not "alphabetical".