2010-02-18 4 views
89

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

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

ответ

140

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

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

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


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

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

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


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

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

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

+6

Хорошо, это можно сделать именно так, но * почему *? Кажется неудобным. Отдельные элементы могут быть удалены из списка напрямую, почему бы не несколько элементов? –

+1

@Joonas: Пункт 40 Эффективной Java, 2-е изд. Описывает обоснование этого. Я вставлю соответствующий раздел, если у вас нет книги. –

+1

Спасибо, именно то, что я искал! Теперь это делает * some * sense :) –

Смежные вопросы