Попытка использовать Comparator для сортировки по имени, игнорировать регистр, а также нулевые значения в первую очередь
У меня проблемы с использованием класса Java 8 Comparator для сортировки списка элементов.
Мой текущий рабочий компаратор ниже:
comparator = Comparator.comparing(Person::getName, Comparator.nullsFirst(Comparator.naturalOrder()));
Это работает: сначала упорядочивает список по имени с нулевыми значениями. Тем не менее, я сейчас пытаюсь игнорировать регистр имен.
Я знаю, что могу написать новый метод получения, который возвращает имя в нижнем регистре, но я не хочу использовать этот подход, поскольку я должен сделать это для нескольких атрибутов.
Глядя онлайн, похоже, я должен использовать String.CASE_INSENSITIVE_ORDER
, но единственные примеры, которые я вижу, не включают спецификацию нулевого порядка.
Я могу сделать что-то вроде этого:
comparator = Comparator.comparing(Person::getName, String.CASE_INSENSITIVE_ORDER);
Однако всякий раз, когда я пытаюсь включить Comparator.nullsFirst
Я заканчиваю тем, что получаю ошибки типа, и не понимаю, как продолжить.
Я пытался сделать цепочку, похожую на
thenComparing(Comparator.nullsFirst(Comparator.naturalOrder))
но это тоже не работает.
Может ли кто-нибудь дать мне несколько советов о том, как я могу связать их вместе, чтобы отсортировать по имени (без учета регистра), а затем упорядочить нули. Я, кажется, путаю себя с типами.
1 ответ
Есть два типа null
s вы можете иметь в своем списке. Вы можете иметь null
Person
ссылки, и вы можете иметь Person
с null
имена.
В первом случае вы должны подать заявку nullsFirst
к базовому компаратору, который вы хотите использовать:
comparator = Comparator.nullsFirst(
Comparator.comparing(Person::getName, String.CASE_INSENSITIVE_ORDER));
Если у вас есть возможность null
имена, вы должны убедиться, что ваш ключ никогда не возвращает null
или что вы подаете заявку nullsFirst
в String.CASE_INSENSITIVE_ORDER
, Второй вариант, конечно, намного проще:
comparator = Comparator.comparing(
Person::getName, Comparator.nullsFirst(String.CASE_INSENSITIVE_ORDER));
Если у вас есть оба варианта (null
ссылки и null
имена), вам придется объединить обе версии и применить nullsFirst
дважды:
comparator = Comparator.nullsFirst(
Comparator.comparing(
Person::getName,
Comparator.nullsFirst(String.CASE_INSENSITIVE_ORDER)
)
);
Если вы объединяете несколько сравнений, как это, внешний nullsFirst
, который гарантирует, что null
Person
s сортируются правильно, могут применяться ко всей цепочке:
comparator = Comparator.nullsFirst(
Comparator.comparing(
Person::getName,
Comparator.nullsFirst(String.CASE_INSENSITIVE_ORDER)
).thenComparing(...)
);