Initialize Set in Java

In this post, we will discuss various methods to initialize set in Java in a single line.


 

Java is often criticized for its verbosity. For example, creating a set containing n elements involves constructing it, storing it in a variable, invoking add() method on it n times, and then maybe wrapping it to make it unmodifiable:

 

 
In this post, we will discuss various methods to initialize set in a single expression.

 

1. Constructor –

We can initialize a set by using HashSet constructor that can accept another collection as shown below:

Any duplicate elements present in the list will be rejected. This approach is not time efficient as we are initially creating an array, converting it to a list and passing that list to create a set.

 

2. Java Collections –

Collections class consists of several static methods that operate on collections and return a new collection backed by a specified collection. Please note that duplicate elements will be rejected.

 

1. Collections.addAll()

Collections.addAll() adds all of the specified elements to the specified collection. Elements to be added may be specified individually or as an array. When elements are specified individually, this method provides a convenient way to add a few elements to an existing collection:

 

2. Collections.unmodifiableSet() –

Alternatively, one can populate a collection using a copy constructor from another collection. One such method is Collections.unmodifiableSet() returns an unmodifiable view of the specified set. Any attempts to modify the returned set will result in an UnsupportedOperationException.

Collections also has unmodifiableSortedSet(SortedSet s) method that returns an unmodifiable view of the specified sorted set.

 

3. Collections.singleton()

If we want a Set containing only a single element, we can use Collections.singleton() that returns an immutable set containing that element. The set will throw an UnsupportedOperationException if any modify operation is performed on it.

 

3. Double Brace Initialization –

Another alternative is to use “Double Brace Initialization”. This creates an anonymous inner class with just an instance initializer in it.

This creates a new class that inherits from HashSet. This approach should be avoided as it costs an extra class at each usage and it also holds hidden references to the enclosing instance and to any captured objects. This may cause memory leaks or problems with serialization.

 

4. Java 8 –

The Java 8 Stream API can be used to construct small sets by obtaining stream from static factory methods and accumulating the input elements into a new set using collectors. For example,

 

1. Collectors.toSet()

Collectors.toSet() returns a Collector that accumulates the input elements into a new Set.

 

2. Collectors.toCollection()

The specification doesn’t guarantee the type of Set returned by toSet(). Even though in Java 8 it returns a HashSet, this might change in future releases. We can use toCollection() to ensure that the returned type of Set is HashSet as shown below:

 

3. Collectors.collectingAndThen()

We could adapt a Collector to perform an additional finishing transformation. For example, we could adapt the toSet() collector to always produce an unmodifiable set with:

 

5. Java 9 –

Java 9 made it convenient to create instances of list with small numbers of elements by providing Sets.of() static factory methods that creates compact, unmodifiable instances of it. For example,

Java 9 provides 12 overloaded versions of this method with one varargs method which can handle any number of elements.

static Set of()
static Set of(E e1)1
static Set of(E e1, E e2)
….
….
static Set of(E e1, E e2, E e3, E e4, . . . E e8, E e9)
static Set of(E e1, E e2, E e3, E e4, . . . E e8, E e9, E e10)
static Set of(E… elements)

 
Now the obvious question is why Java 9 has included so many extra methods when only var-args can suffice? The reason is there’s a subtle runtime performance advantage. The var-args version is likely to run slower than the overloadings that do not use varargs. This is because every invocation of a varargs method will cause an array allocation and initialization and not to forget GC overhead.

As per Javadoc, the Set instances created by Set.of() have the following characteristics:

  1. They are structurally immutable. Elements cannot be added, removed, or replaced. Calling any mutator method will always cause UnsupportedOperationException to be thrown. However, if the contained elements are themselves mutable, this may cause the Set’s contents to appear to change.
     
  2. They disallow null elements. Attempts to create them with null elements result in NullPointerException.
     
  3. They are serializable if all elements are serializable.
     
  4. They reject duplicate elements at creation time. Duplicate elements passed to a static factory method result in IllegalArgumentException.
     
  5. The order of elements in the list is the same as the order of the provided arguments, or of the elements in the provided array.
     
  6. They are value-based. Callers should make no assumptions about the identity of the returned instances. Factories are free to create new instances or reuse existing ones. Therefore, identity-sensitive operations on these instances (reference equality (==), identity hash code, and synchronization) are unreliable and should be avoided.
     

If we need a Set that can expand or shrink, we can use –

 
Please note that unlike static methods on classes, static methods on interfaces are not inherited, so it will not be possible to invoke them via an implementing class, nor via an instance of the interface type.

 

6. Guava

Guava also provides several static utility methods pertaining to Set instances.

Refer: Initialize Set using Guava in Java

 

7. Apache Commons Collections

Apache Commons Collections SetUtils class provides unmodifiableSet() that returns an unmodifiable set backed by the given set. It throws a NullPointerException if the given set is null and an UnsupportedOperationException if any modify operation is performed on it.

 
 
References: JEP 269: Convenience Factory Methods for Collections

 
Thanks for reading.

Please use ideone or C++ Shell or any other online compiler link to post code in comments.
Like us? Please spread the word and help us grow. Happy coding 🙂
 





Leave a Reply

Notify of
avatar
wpDiscuz