In Java 9 new static factory methods were introduced on the Set interface, called of(), which accept multiple elements, or even an array of elements.
I wanted to turn a list into a set to remove any duplicate entries in the set, which can be done (prior to Java 9) using:
Set<String> set = new HashSet<>();
set.addAll(list);
But I thought it would be cool to use this new Java 9 static factory method doing:
Set.of(list.toArray())
where the list
is a List of Strings, previously defined.
But alas, java threw an IllegalArgumentException
when the elements were duplicates, also stated in the Javadoc of the method. Why is this?
Edit: this question is not a duplicate of another question about a conceptually equivalent topic, the Map.of() method, but distinctly different. Not all static factory of() methods behave the same. In other words, when I am asking something about the Set.of() method I would not click on a question dealing with the Map.of() method.
The Set.of()
factory methods produce immutable Set
s for a given number of elements.
In the variants that support a fixed number of arguments (static <E> Set<E> of()
, static <E> Set<E> of(E e1)
, static <E> Set<E> of(E e1,E e2)
, etc...) the requirement of not having duplicates are easier to understand - when you call the method Set.of(a,b,c)
, you are stating you wish to create an immutable Set
of exactly 3 elements, so if the arguments contain duplicates, it makes sense to reject your input instead of producing a smaller Set
.
While the Set<E> of(E... elements)
variant is different (if allows creating a Set
of an arbitrary number of elements), it follows the same logic of the other variants. If you pass n
elements to that method, you are stating you wish to create an immutable Set
of exactly n
elements, so duplicates are not allowed.
You can still create a Set
from a List
(having potential duplicates) in a one-liner using:
Set<String> set = new HashSet<>(list);
which was already available before Java 9.