коллекция против списка против массивов как тип возврата для метода EJB - PullRequest
10 голосов
/ 12 июля 2011

Мне недавно сказали, что коллекцию следует отдавать предпочтению List, как возвращаемому значению метода EJB.Аргумент заключается в том, что в целом сбор является более общим, то есть дает вам возможность изменять базовую структуру данных, не влияя на клиентов.И если это гибкость, которую вы хотите иметь как дизайнер, тогда использование коллекции будет более целесообразным.Но тогда не имеет ли смысла возвращать только массив вместо коллекции?

А как это повлияет на производительность?

Заранее спасибо.

Ответы [ 4 ]

29 голосов
/ 12 июля 2011
  • Предпочитать коллекции массивам;Используйте дженерики
  • Используйте интерфейсы вместо конкретных классов

Тогда у вас обычно есть 4 варианта: List, Set, Collection и Iterable.Здесь все зависит от того, какую семантику вы хотите включить.

  • Если это внутренний API - выберите его на основе характеристик коллекции:
    • содержит только уникальные элементы?Set
    • потребуются ли клиентам произвольный доступ к нему?List
    • нужно ли клиентам изменять его (добавлять, удалять) (без двух вышеуказанных характеристик)?Collection
    • потребуются ли клиентам итерации?Iterable
  • Если это веб-служба, то это не имеет значения - она ​​сериализуется таким же образом.

(Примечание: существуют некоторые интерфейсы сборас более конкретной семантикой: Queue, Deque, Map, Bag, Multiset и т. д. - но это будет довольно очевидно, когда вам нужно будет их вернуть)

5 голосов
/ 12 июля 2011

Коллекции в целом предпочтительнее массивов, особенно начиная с Java5, где они стали универсальными. Это дает вам безопасность типов и множество потенциальных дополнительных функций, которые недоступны в массивах (например, поведение Set / Queue и т. Д.) - на самом деле они вообще не сопоставимы с массивами. Среди коллекций ArrayList является прямой аналогией массива, и, будучи реализованным поверх массива, его производительность сопоставима с собственным массивом.

Что касается Collection vs List (или некоторого другого более специфического интерфейса), я лично предпочел бы более специфический интерфейс, как характеристики и поведение, например. Список против набора очень отличается. В хорошо разработанном интерфейсе вы должны знать (и указывать) заранее, возвращаете ли вы, например, Set, Dequeue или List. Если вы возвращаете коллекцию, все ваши клиенты могут (кроме добавления / удаления элементов) перебирать ее, что может быть недостаточно для них.

2 голосов
/ 12 июля 2011

По моему мнению, использование Collection в противоположность более конкретному интерфейсу, например List или Set, должно быть сделано намеренно. Вы будете использовать интерфейс Collection для всех случаев, когда более конкретный интерфейс расширяет интерфейс Collection, то есть для истинных коллекций. Но вы не можете сделать то же самое для других интерфейсов, таких как Map, которые представляют сопоставления, а не коллекции. Это означало бы, что над вашими знаками EJB-интерфейса нужно очень внимательно относиться.

Как указывалось в другом ответе Сюаня, если вы намереваетесь вернуть упорядоченную коллекцию, тогда вы должны использовать List. Вы можете задокументировать это поведение вашего интерфейса, но в этом нет смысла; подпись метода должна передать это. Также обратите внимание, что List s может содержать дубликаты, поэтому, если вы намереваетесь вернуть коллекцию без дубликатов, имеет больше смысла возвращать Set вместо List или Collection. Чтобы переформулировать мое мнение, коллекция, возвращаемая методом EJB, должна максимально точно отражать свойства коллекции, не ссылаясь на конкретный тип; попытка использовать документацию для передачи этого может не дать желаемых результатов во время разработки клиентов EJB.

Что касается использования массивов, я бы рекомендовал избегать их, особенно массивов типа Object[]. Их легко использовать и преобразовывать в слабо типизированные объекты передачи данных, что требует обширной документации о том, как должен обрабатываться каждый элемент массива. Тот же совет относится и к коллекциям, но большинство людей склонны злоупотреблять массивами вместо коллекций, или, по крайней мере, это было моим наблюдением.

Последнее замечание приводит к использованию дженериков в коллекциях. Если ваш контейнер (и косвенно версия спецификации EJB) позволяет вам использовать обобщенные интерфейсы для ваших методов, тогда используйте их для дополнительной безопасности типов. В конце концов, заставить вашего клиента обрабатывать List<DomainObject> - лучшее проектное решение, чем позволить клиенту обрабатывать List или List<Object>. Я хотел бы еще раз подчеркнуть аспект поддержки контейнеров, поскольку интерфейсы EJB 2.x не поддерживают обобщенные элементы (это было моим наблюдением), в то время как EJB 3.x поддерживает обобщенные элементы (но контейнер может подавиться при развертывании или во время выполнения) и будет требовать, чтобы ваши локальные и удаленные интерфейсы кодировались определенным образом; например, WebLogic 10.3.x требует, чтобы вы указали универсальные шаблоны в суперинтерфейсе, который расширен как локальный / удаленный интерфейс.

1 голос
/ 12 июля 2011

Во-первых, это не проблема только с EJB. Это относится ко всем определениям методов.

Фактически, то же самое относится и к определению параметров и переменных:

 List<String> myList = new ArrayList<String>();

Чем шире данное определение, тем больше свободы во время реализации. Скажите, что я определяю:

 public class Numbers {
   public ArrayList getPrimesUnder(int N) {
   }
 }

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

Почему бы не использовать коллекцию в этом случае? Потому что список является специализацией коллекции, которая упорядочена. Если я хочу вернуть заказанные результаты, я буду использовать Список. Если они не заказаны, то Коллекция лучше подойдет.

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