Предпочтение изменяемых или неизменяемых коллекций в качестве параметров метода - PullRequest
7 голосов
/ 07 мая 2020

Я пишу библиотечный метод, который будет использоваться в нескольких местах. Один из параметров метода - это набор объектов, и метод не изменяет эту коллекцию. Следует ли в сигнатуре метода указывать изменяемую или неизменяемую коллекцию?

Вариант 1: изменяемая коллекция в качестве параметра

public static void foo(List<Bar> list) {
  // ...
}

Плюсы: клиенты могут передавать в зависимости от того, какое из List<Bar> или ImmutableList<Bar> больше им удобно.

Минусы: Не сразу видно, что параметр list не будет видоизменен. Клиенты должны прочитать документацию и / или код, чтобы понять это. В любом случае клиенты могут делать ненужные защитные копии.

Вариант 2: неизменяемая коллекция в качестве параметра

public static void foo(ImmutableList<Bar> list) {
  // ...
}

Плюсы: у клиентов есть гарантия, что параметр list не будет изменен.

Минусы: если у клиента есть List<Bar>, они должны сначала преобразовать его в ImmutableList<Bar> перед вызовом foo. Это преобразование занимает немного времени, и оно принудительно для клиентов, нравится им это или нет.


Примечание. Для целей этого вопроса давайте предположим, что все клиенты будут иметь доступный ImmutableList Guava, например, потому что библиотека и клиентский код все принадлежат той же кодовой базе, которая уже использует ImmutableList в другом месте.

Ответы [ 2 ]

3 голосов
/ 07 мая 2020

Как создателя foo() API, это не ваше дело. Вы берете список и не изменяете его, и все. Фактически, ваш код не заботится о изменчивости списка (это проблема вызывающего): так что задокументируйте свое намерение и остановитесь на этом.

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

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

Другими словами, задокументируйте свой так, как вы собираетесь их реализовать, и предоставьте вызывающей стороне выбор реализации списка. Причины их выбора будут разными (т. Е. Не всегда будет зависеть только то, будете ли вы изменять список).

1 голос
/ 08 мая 2020

Оставьте List.

Вот некоторые ситуации, которые следует учитывать:

  • Collections.synchronizedCollection не изменяет коллекцию клиента.
    • Если бы он заставлял клиентов вводить неизменяемую коллекцию, было бы бесполезно делать ее синхронизированной коллекцией, поскольку неизменяемая коллекция уже была бы потокобезопасной.
  • Collections.frequency не изменяет коллекцию клиента.
    • Чтобы проверить частоту, пользователи будут вынуждены терпеть лишние накладные расходы на перенос элементов в новую коллекцию.

Эти причины не являются причиной того, что JDK не предоставляет неизменяемый интерфейс. Эти причины объясняются в документации . В случае synchronizedCollection, хотя он не изменяет коллекцию клиента, он возвращает изменяемое представление коллекции клиента; некоторые сказали бы, что эта функция здесь не применима. Однако frequency и другие функции запросов по-прежнему остаются сильными.

Вы не должны ограничивать клиентов с целью рекламировать безопасность и ничего более. Должно быть больше оправданий, иначе ваша попытка помочь может стать бременем для клиента. В некоторых случаях ваша цель может противоречить тому, что выполняет функция / система, например, в примере synchronizedCollection.

Хорошо поддерживать безопасность, но если ваша система навязывает ее своим клиентам без система, извлекающая выгоду из этого, будет злоупотреблением властью; это не ваше решение.


ernest_k делает действительно хорошее замечание в своем ответе , предлагая вам проанализировать, за что ваша система должна отвечать и за что клиент должен нести ответственность. В этом случае клиент должен решать, является ли коллекция неизменной или нет, поскольку ваша система не заботится о изменчивости. Как он выразился: « это не ваше дело », с чем я согласен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...