What is the benefit for Collections.singleton() to return a Set instead of a Collection?
I'm not sure there's a "benefit" or "advantage" per se? It's just the method that returns a singleton Set
, and happens to be the default implementation when you want a singleton Collection
as well, since a singleton Collection
happens to be a mathematical set as well.
Immutable
The benefit is found in the first adjective read in that JavaDoc documentation: immutable.
There are times when you are working with code that demands a Set
(or List
, etc.). In your own context you may have a strict need for only a single item. To accomplish your own goal of enforcing the rule of single-item-only while needing to present that item in a set, use a Set
implementation that forbids you from adding more than one item.
“Immutable” on Collections::singleton
means that, once created, the resulting Set
object is guaranteed to have one, and only one item. Not zero, and not more than one. No more can be added. The one item cannot be removed.
For example, imagine your code is working with an Employee
object representing the CEO (Chief Executive Officer) of your company. Your code is explicitly dealing with the CEO only, so you know there can be only one such Employee
object at a time, always one CEO exactly. Yet you want to leverage some existing code that creates a report for a specified collection of Employee
objects. By using Collection.singleton
you are guaranteed that your own code does not mistakenly have other than one single employee, while still being able to pass a 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 and later offers new interface methods Set.of
and List.of
to th same effect, an immutable collection of a single element.
Set< Pet > pet = Set.of( someDog ) ;
But sibling of
methods are overloaded to accept any number of elements to be in the immutable collection, not just one element.
Set< Pet > pets = Set.of( someDog , someOtherDog , someCat ) ;
I wondered the same thing and came across your question in my research. Here is my conclusion:
Returning a Set
keeps the Collections API clean.
Here are the methods for getting a singleton Collection:
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)
What if the API designers decided on having a singletonSet
method and singleton
method? It would look like this:
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)
Is the singleton
method really necessary? Let's think about why we would need some of these methods.
Think about when you would call singletonList
? You probably have an API that requires List
instead of Collection
or Set
. I will use this poor example:
public void needsList(List<?> list);
You can only pass a List
. needsList
hopefully needs the data indexed and is not arbitrarily requesting a List
instead of a Collection
.
However, you could also pass a List
to a method that required any Collection
:
public void needsAnyCollection(Collection<?> collection);
But if that is the case, then why use a List
? A List
has a more complicated API and involves storing indexes. Do you really need the indexes? Would a Set
not suffice? I argue that you should use a Set
, because needsAnyCollection
does not care about the order.
This is where singletonSet
really shines. You know that if the collection is of size 1 (singleton), then the data must be unique. Collections of size 1 are coincidentally a Set.
There is no need for a method which returns a singleton of type Collection
, because it is accidentally a Set
.