Почему защищен метод Java AbstractList removeRange()?

Кто-нибудь знает, почему метод removeRange в AbstractList (а также в ArrayList) protected? Это похоже на довольно четкую и полезную операцию, но, тем не менее, для ее использования мы вынуждены подклассифицировать реализацию List.

Есть ли какое-то скрытое обоснование? Для меня это совершенно необъяснимо.

Ответ 1

Да, потому что это не то, как вы удаляете диапазон из внешнего кода. Вместо этого сделайте следующее:

list.subList(start, end).clear();

Это фактически вызывает removeRange за кулисами.


OP спрашивает, почему removeRange не является частью публичного API List. Причина описана в пункте 40 эффективной Java 2-й редакции, и я цитирую ее здесь:

Существует три метода сокращения слишком длинных списков параметров. Один из них заключается в том, чтобы разбить метод на несколько методов, каждый из которых требует только подмножество параметров. Если это делается небрежно, это может привести к слишком большому количеству методов, но также может помочь уменьшить количество методов путем увеличения ортогональности. Например, рассмотрим интерфейс java.util.List. Он не предоставляет методы для поиска первого или последнего индекса элемента в подсписке, оба из которых потребуют трех параметров. Вместо этого он предоставляет метод subList, который принимает два параметра и возвращает вид подсписчика. Этот метод можно комбинировать с методами indexOf или lastIndexOf, каждый из которых имеет один параметр, чтобы получить требуемую функциональность. Кроме того, метод subList может быть объединен с любым методом, который работает с экземпляром List для выполнения произвольных вычислений на подсписках. Полученный API имеет очень высокое отношение мощности к весу.

Можно утверждать, что removeRange не имеет такого количества параметров и, следовательно, вероятно, не является кандидатом на это лечение, но учитывая, что существует способ вызвать removeRange через subList, нет оснований для загромождать интерфейс List с избыточным методом.


Документация AbstractList.removeRange гласит:

Этот метод вызывается операцией clear в этом списке и его списках. Переопределение этого метода для использования внутренних функций реализации списка может существенно улучшить производительность операции clear в этом списке и его сублистах.

Также см. реализацию OpenJDK AbstractList.clear и SubList.removeRange.