tldr
Это дизайнерское решение, смешанное с некоторыми историческими причинами. Можно было бы добавить list.sort()
, но это не могло обеспечить безопасность во время компиляции, только во время выполнения. Что было бы довольно странным и необычным дизайном для JDK.
Collections # sort
Коллекции, поскольку они могут указывать границы типов в объявлении метода, имеют возможность принудительно Comparable
элементов:
public static <T extends Comparable<? super T>> void sort(List<T> list)
Таким образом, метод может гарантировать, что коллекция содержит Comparable
элементов. Так что Comparator
не требуется.
Список # сортировка
List
не может этого сделать. Его обобщенный тип c должен разрешать все, вы должны иметь возможность использовать List<Dog>
, хотя, возможно, это не Comparable
.
Так что если будет list.sort()
, то этот метод будет нужно выяснить, является ли список обобщенных c type T
равным Comparable
или нет. Но эта информация присутствует только во время выполнения, мы хотим, чтобы она была во время компиляции для хорошего дизайна.
Поскольку это может привести к плохому дизайну, list.sort()
не существует. Следовательно, дополнительный метод форсирования Comparator
, который может обеспечить безопасность во время компиляции ..
list.sort (null)
Наличие list.sort(null)
вместо list.sort()
, явно выбор дизайна , на мой взгляд, хороший. Как сказано выше, List
не может обеспечить безопасность во время компиляции. Таким образом, единственный выбор - go для обеспечения безопасности во время выполнения, что не так хорошо.
Наличие list.sort()
, которое работает только иногда и выдает исключение, в противном случае это будет странный дизайн выбор. Однако звонок типа list.sort(null)
намного понятнее любому пользователю. В частности, более ясно, что это будет охватываться решениями во время выполнения, а не проверками во время компиляции.
Вы можете предпочесть сделать это явным и дать ему тривиальный Comparator
, который использует естественный порядок:
list.sort(Comparator.naturalOrder());
Это было бы по крайней мере еще понятнее для читателя.
История
Теперь вы можете задаться вопросом, почему List.sort(null)
даже является поддерживаемой функцией и почему они не требуют от вас явного Comparator
всегда. Я не могу заглянуть в мысли разработчиков, но я подозреваю, исторические причины. Подобных примеров в JDK довольно много, особенно с сортировкой.
Это главным образом потому, что Java поддерживает обратную совместимость. Обобщения были введены с Java 5, поэтому все, что существовало до этого, имело дело с контейнерами, не было разработано с учетом безопасности типов.
Есть несколько тесно связанных примеров:
Arrays#sort(Object[])
(с Java 1.2) не принудительно Comparable
. Поэтому им пришлось добавить дополнительную перегрузку в Java 5 Arrays.sort(T[], Comparator)
, точно так же, как в примере List
. - Метод
Collections.sort(T[], Comparator)
фактически принимает null
для компаратора. Плохой дизайн, но он был сделан тогда, когда дженерики еще не существовали. Поэтому они больше не могли удалять эту функцию . - Интересно, что они решили разрешить
List.sort(Comparator)
, новый метод, также поддерживающий null
. Однако в Stream.sort(Comparator)
они этого не сделали. Это странное несоответствие в JDK.