Какая польза для 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
просто имеет смысл, потому что он ближе к математическому определению, он просто чувствует себя естественным.