Какая польза для Collections.singleton() для возврата набора вместо коллекции?

Метод Collections.singleton() возвращает Set с этим единственным аргументом вместо Collection.

Почему это так? Из того, что я вижу, кроме Set, являющегося подтипом Collection, я не вижу никакого преимущества... Это только потому, что Set расширяет Collection в любом случае, поэтому нет причин не делать этого?

И да, есть также Collections.singletonList(), но это другое дело, поскольку вы можете получить доступ к случайным элементам из List с помощью .get()...

Ответ 1

Я не уверен, что есть "преимущество" или "преимущество" как таковое? Это просто метод, который возвращает singleton Set, и, случается, является реализацией по умолчанию, когда вы хотите использовать singleton Collection, так как singleton Collection также является математическим набором.

Ответ 2

Неизменное

Преимущество найдено в первом прилагательном, которое читается в что документация JavaDoc: неизменная.

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

"Неизменяемый" на Collections::singleton означает, что после создания результирующий объект Set гарантированно имеет один и только один предмет. Не равен нулю, и не более одного. Больше нельзя добавить. Один элемент не может быть удален.

Например, представьте, что ваш код работает с объектом Employee, представляющим генерального директора (главного исполнительного директора) вашей компании. Ваш код явно имеет дело только с генеральным директором, поэтому вы знаете, что за один раз может быть только один такой объект Employee, всегда один генеральный директор. Однако вы хотите использовать какой-то существующий код, который создает отчет для указанной коллекции объектов Employee. Используя Collection.singleton, вы гарантированно убедитесь, что ваш собственный код не ошибочно имеет кроме одного сотрудника, хотя он все еще может передать Set.

Set< Employee > ceo = Collections.singleton( new Employee( "Tim Cook" ) ) ;  // Always exactly one item in this context, only one CEO is possible.

ceo.add( … ) ;     // Fails, as the collection is immutable.
ceo.clear() ;      // Fails, as the collection is immutable.
ceo.remove( … ) ;  // Fails, as the collection is immutable.

someReport.processEmployees( ceo ) ;

Java 9: ​​ Set.of и List.of

Java 9 и более поздние версии предлагают новые методы интерфейса Set.of и List.of к такому же эффекту, неизменяемой коллекции одного элемента.

Set< Pet > pet = Set.of( someDog ) ;

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

Set< Pet > pets = Set.of( someDog , someOtherDog , someCat ) ;

Ответ 3

Я задавался вопросом то же самое и наткнулся на ваш вопрос в своих исследованиях. Вот мой вывод:

Возврат Set сохраняет API коллекций в чистоте.

Ниже приведены методы получения коллекции Singleton:

  • public static <T> Set<T> singleton(T o)
  • public static <T> List<T> singletonList(T o)
  • public static <K,V> Map<K,V> singletonMap(K key, V value)

Что, если дизайнеры API решили использовать метод singletonSet и singleton? Это будет выглядеть так:

  • public static <T> Collection<T> singleton(T o)
  • public static <T> Set<T> singletonSet(T o)
  • public static <T> List<T> singletonList(T o)
  • public static <K,V> Map<K,V> singletonMap(K key, V value)

Действительно ли нужен метод singleton? Подумайте, зачем нам нужны некоторые из этих методов.

Подумайте, когда вы назовёте singletonList? Вероятно, у вас есть API, для которого требуется List вместо Collection или Set. Я воспользуюсь этим плохим примером:

public void needsList(List<?> list);

Вы можете передать только List. needsList надеюсь, что данные будут проиндексированы и не будут произвольно запрашивать List вместо Collection.

Однако вы также можете передать List методу, который потребовал бы любой Collection:

public void needsAnyCollection(Collection<?> collection);

Но если это так, то зачем использовать List? A List имеет более сложный API и включает в себя хранение индексов. Вам действительно нужны индексы? Не хватит ли Set? Я утверждаю, что вы должны использовать Set, потому что needsAnyCollection не заботится о порядке.

Здесь singletonSet действительно сияет. Вы знаете, что если коллекция имеет размер 1 (singleton), то данные должны быть уникальными. Коллекции размером 1 совпадают с набором.

Нет необходимости в методе, который возвращает одноэлемент типа Collection, потому что он случайно Set.

Ответ 4

Не все списки представляют собой произвольный доступ, просто возьмите LinkedList (произвольный доступ в API, а не в реализацию) в качестве контр-примера. Кстати, я согласен с Луи Вассерманом, Set просто имеет смысл, потому что он ближе к математическому определению, он просто чувствует себя естественным.