There's another option:
Set<String> set = new HashSet<>();
Collections.addAll(set, "a", "b", "c");
Like Arrays.asList()
and Stream.of()
, this uses varargs, so an array is implicitly created. Unlike those options, however, no additional objects are instantiated. If you want a solution where no extra objects are created, addAll()
is better.
One drawback is that the collection is modified after creation, instead of being populated during construction. It might be unlikely that code is introduced later that lets this uninitialized collection escape, but it's something to consider.
Since you also want to be succinct, this approach loses points aesthetically too. That can be remedied with your own utility method:
@SafeVarargs
public static
<C extends Collection<T>, T> C newCollection(Supplier<? extends C> ctor, T... elements)
{
C c = ctor.get();
for (T element : elements)
c.add(element);
return c;
}
Set<String> set = newCollection(HashSet::new, "a", "b", "c");
But then, you have to weigh that solution against the third option, using Stream.of()
. It is just as succinct, and while it's a bit less efficient, it offers a great deal more flexibility. For example, it is easy to add additional operations so that you can map types, or use a different collection:
List<URI> uris = Stream.of("x", "y", "z").map(base::resolve).collect(Collectors.toList());
Overall, this option is probably the easiest to read and maintain, and so it will be the best option for most new code.
The second option, creating an anonymous inner class, has nothing to recommend it. Forget about it!