Comparator.comparing() без nullsFirst — NPE на первом null
Сортировка списка по полю, которое иногда null, кажется безопасной операцией. Comparator.comparing(Order::getShippedAt) компилируется и работает на тестовых данных, где даты у всех заказов заполнены.
В проде часть заказов ещё не отправлена, shippedAt = null. Comparator.comparing() внутри вызывает compareTo() на возвращённых значениях, а Comparable для дат не умеет сравнивать с null — это NullPointerException прямо в момент sort(), причём стектрейс укажет на TimSort, а не на ваш код.
orders.sort( Comparator.comparing( Order::getShippedAt, Comparator.nullsFirst( Comparator.naturalOrder() ) ) );
Ловушка: nullsFirst и nullsLast сами оборачивают компаратор, а не заменяют его — без вложенного naturalOrder() или своего компаратора код не скомпилируется. Ещё спросят: что если сортировка идёт по нескольким полям через thenComparing, а null может быть в любом из них? Тогда nullsFirst/nullsLast нужно на каждом уровне отдельно, дефолт не наследуется дальше по цепочке.
Comparable молчит про null в контракте — это забота вызывающего кода, не JVM.
Тренажёр: 600 вопросов, мок с таймером, план повторов
senior·base — что спрашивают на самом деле
В этом посте были ссылки, но мы их удалили по правилам Сетки