Java: возврат набора

Что лучший способ состоит в том, чтобы возвратить набор в Java?

Я должен позволить вызывающей стороне обеспечивать набор для добавления к? Или просто возвратите a List<> или Set<> из объектов? Или оба?

public class Item { ... }

public class SomeOtherClass
{
  private List<Item> myItems;

  public List<Item> getItems()
  { 
     return Collections.unmodifiableList(this.myItems); 
  }
  public void collectItems(Collection<? super Item> target)
  {
     target.addAll(myItems);
  }
}

примечание: вышеупомянутый пример принимает предварительное существование списка, который может быть немедленно возвращен. Я также интересуюсь соответствующим ответом, когда такой список ранее не существует и должен быть сгенерирован, когда вызывающая сторона называет getItems () или collectItems (). (Я переименовал collectItems на основе вопроса, поднятого Mykola.)

6
задан Jason S 1 February 2010 в 16:48
поделиться

7 ответов

Я просто предпочитаю метод List getItems(). Нет никакого реального преимущества в void getItems(Collection target) над вызывающим, просто выполняющим myCollection.addAll(foo.getItems()) или другим способом. Collections.unmodifiableXYZ только создаёт обёртку, а не полную копию коллекции, поэтому если обёртка используется немедленно и отбрасывается, то она никогда не выйдет из первого поколения и будет собрана быстро, с небольшими накладными расходами.

Если коллекция элементов не всегда реализуется, вы можете рассмотреть возможность возврата getItems Iterable , когда вы не знаете, сколько элементов там есть. Если вы знаете количество элементов и можете написать итератор для них, то легко написать пользовательский подкласс AbstractCollection и вернуть его.

6
ответ дан 8 December 2019 в 12:59
поделиться

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

0
ответ дан 8 December 2019 в 12:59
поделиться

Учитывая то, как работает Java, вы обычно ожидаете возвратную версию.

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

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

0
ответ дан 8 December 2019 в 12:59
поделиться

Примечание. Возвращение набора и возврата списка имеет разные последствия.

Набор не имеет дупликатов и не указанного порядка. Добавление элемента на множество может привести к другому порядку элементов.

Список может содержать дубликаты и добавление элемента не будет (вообще) изменить общий порядок списка.

Что касается того, как вы возвращаете список, я бы использовал первую форму:

public List<Item> getItems()
{ 
   return Collections.unmodifiableList(this.myItems); 
}

Я не могу придумать ситуацию, когда последняя форма будет любого выгоды. Список не похож на массив, где пространство может быть предварительно выделено. Таким образом, нет экономии производительности, проходя в списке.

0
ответ дан 8 December 2019 в 12:59
поделиться

Единственная причина, по которой я могу думать о том, чтобы заполнить существующую коллекцию, а не создавать новую, это когда у вас возникают проблемы с типом объекта в коллекции. Как и в случае с функцией Java библиотеки toArray(Object[] a), где программа на этапе компиляции не знает, какого типа будут элементы массива, так и не может просто вернуть, например, String[]. Поэтому вместо этого в массиве с соответствующим типом элементов передается вызов, и они заполняют его.

90% времени вы точно знаете, какие типы объектов вы хотите вернуть, так что вы можете просто сделать это.

0
ответ дан 8 December 2019 в 12:59
поделиться

Вы можете поменять подпись, чтобы вернуть коллекцию или отсрочку. Для возврата Iterable, вы можете вернуть что-то новое - Iterable(myItems.iterator()) вместо myItems напрямую, чтобы клиент, возможно, не пытался проиграть список (и изменить его). Если вы не хотите, чтобы они модифицировали список, также подумайте о возвращении итератора, но обратите внимание, что Iterable лучше, так как вы можете напрямую использовать его в for-each циклах.

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

0
ответ дан 8 December 2019 в 12:59
поделиться

. Лучше (если не возникают проблемы с производительностью) возвращать результат в функции через return . Так становится более понятно, что происходит.

Если вы выберете второй вариант (заполнить коллекцию клиента), было бы лучше переименовать функцию из getItems в что-то вроде fillWithItems , чтобы избежать неоднозначного кода.

Также не забывайте о JavaBeans и их соглашениях.

12
ответ дан 8 December 2019 в 12:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: