Reputation: 4049
What is the most succinct and efficient way to create a Set with data in it in java? I have found a couple ways that seem tedious i.e.
Set<String> set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");
Set<String> set1 = new HashSet<>(Arrays.asList("a", "b", "c"));
Set<String> set2 = new HashSet<String>() {{ add("a"); add("b"); add("c"); }};
Set<String> set3 = Stream.of("a", "b", "c").collect(toSet());
Is there a way to simply say HashSet<String> set = new HashSet("a", "b", "c");
so that the Set gets created with no extra objects created or extra method calls?
Upvotes: 2
Views: 5717
Reputation: 269817
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!
Upvotes: 3
Reputation: 198341
No, there is not. You've successfully named all the ways built into Java.
The first of these options will be most efficient, if not necessarily the most succinct.
The third option has a number of serious flaws, most noticeably that if you use it in a non-static method you can cause memory leaks by holding an unused reference to the enclosing instance.
Upvotes: 2