Java Set Tutorial

Java Set Tutorial

by Ioannis Makris

In this article, we will show you to use the Java Set interface through detailed examples.

1. What is the Java Set interface?

The set interface is an unordered collection of objects that cannot store duplicate values and implements the mathematical set. This interface contains the methods inherited from the Collection interface and adds a feature that restricts the insertion of the duplicate elements. In this collection, you can add any Java object, and you can even mix objects of different types in the same Set.

2. How to create a Set object?

As we already know the Set is an interface so we cannot create Set objects but for every problem, there is a solution! In order to use the functionalities of the Set interface and create objects, we can use these four classes that are defined in the Collections framework and implement the Set interface:

  • HashSet
  • TreeSet
  • EnumSet
  • LinkedHahSet

So with the help of one of them, the importing of the java.util package at the beginning of the program and the introduction of Generics in Java 1.5, which restricts the type of object that can be stored in the Set, we can create an object. Here is an example:

Set<Obj> animals = new HashSet<>(Obj);

Obj is the type of object to be stored in a Set such as String, int, long, etc.

3. Java Set Interface Implementations

3.1 Which are the Set Implementations?

Now it’s time to analyze the four implementations of the Set interface. Since Set is an interface you need to instantiate a concrete implementation of the interface in order to use it. You can choose between the following Set implementations in the Java Collections API:

  • java.util.HashSet
  • java.util.TreeSet
  • java.util.EnumSet
  • java.util.LinkedHashSet
Image 1. Set Implementations

Each of these Set implementations behave a little differently to the order of the elements when iterating the Set, and the time it takes to insert and access elements in the sets.

  • HashSet is backed by a HashMap. It makes no guarantees about the sequence of the elements when you iterate them.
  • EnumSet provides an efficient way to store enum values than other set implementations. Furthermore, it only stores the enum values of a specific enum. The JVM already knows all the possible values of the set. As a result, the enum sets are internally implemented as a sequence of bits that specify whether elements are present in the enum set or not.
  • LinkedHashSet differs from HashSet by guaranteeing that the order of the elements during iteration is the same as the order they were inserted into the LinkedHashSet. If we insert an element that is already in the LinkedHashSet it will not change the order.
  • TreeSet uses a Tree Data Structure for storage. The ordering of the elements is maintained by a set using their natural ordering whether we provide a comparator interface that is used to order the objects, or not.

3.2 Time Complexity of every implementation

Here is the average time complexity of every implementation of Set. These are:

SetAddRemoveContainsNextSizeData Structure
HashSetO(1)O(1)O(1)O(h/n)O(1)Hash Table
TreeSetO(log n)O(log n)O(log n)O(log n)O(1)Red-black tree
EnumSetO(1)O(1)O(1)O(1)O(1)Bit Vector
LinkedHashSetO(1)O(1)O(1)O(1)O(1)Hash Table+ Linked List
Table 1. Time Complexity

4. Interfaces that extend Set

Image 2. Interfaces that extend Set

The Set interface is also extended by these two sub-interfaces and implemented by TreeSet. These are:

  • SortedSet: This interface contains the methods inherited from the Set interface and adds a feature that stores all the elements in this interface to be stored in a sorted manner.
  • NavigableSet: This interface inherits from the SortedSet interface. It behaves like a SortedSet with the difference that it has navigation methods available in addition to the sorting mechanisms of the SortedSet. 

5. Set Interface Methods

There are several methods available in the set interface which we can use to do a certain operation on our sets. These methods are :

add(Element)This method is used to add a specific element to the set. The function adds the element only if the specified element is not already present in the set else the function returns false.
addAll(Element)This method is used to append all of the elements from the mentioned collection to the existing set and they are added randomly without following any specific order.
clear()This method is used to remove all the elements from the set but not delete the set.
contains(Element)This method is used to check if a specific element is present in the Set.
containsAll(collection)This method is used to check whether the set contains all the elements.
hashCode()This method is used to get the hashCode value for this instance of the Set and it returns an integer value which is the hashCode value.
isEmpty()This method is used to check whether the set is empty or not.
iterator()This method is used to return the iterator of the set and the elements are returned in random order.
remove(element)This method is used to remove the given element from the set. This method returns true if the element is present or else it returns False
removeAll(collection)This method is used to remove all the elements from the collection and returns true.
size()This method is used to get the size of the set and returns the number of elements.
toArray()This method is used to form an array of the same elements.
retainAll(collection)This method is used to retain all the elements from the set which are mentioned in the given collection. This method returns true if this set changes as a result of the call.
Table 2. Set Interface Methods

6. Set Interface Example

Here we can see a Set Interface example where we use some of the set methods:

public class SetExample {
        public static void main(String args[]) {

            Set<Integer> set = new HashSet<Integer>();
            set.addAll(Arrays.asList(new Integer[]{1, 6, 4, 7, 3, 9, 8, 2, 12, 11, 20}));

            System.out.println("Original Set :" + set);
            System.out.println("Set Size:" + set.size());
            System.out.println("Set contains element 2:" + set.contains(2));
            System.out.println("Original Set :" + set);

            Set<Integer> secondSet = new HashSet<Integer>();
            secondSet.addAll(Arrays.asList(new Integer[]{1, 7, 3, 9, 11, 20}));
            System.out.println("Final Set :" + set);

The output is:

Original Set :[1, 2, 3, 36, 4, 20, 6, 7, 8, 9, 11, 12]
Set Size:12
Set contains element 2:true
Original Set :[2, 3, 36, 4, 20, 6, 7, 8, 9, 11, 12]
Final Set :[2, 36, 4, 6, 8, 12]

6. Java Set vs. List

We can say that Set and List are quite similar but there are two important differences between them. These are:

  • Firstly, the same element cannot occur more than once in a Java Set. This is different from Java List where each element can occur more than once.
  • And secondly, List can be inserted in both forward and backward directions using ListIterator while Set can be traversed only in a forward direction with an iterator.

7. Conclusion

By now you should be able to know when to use the Java Set Interface and how to use it in the most efficient way. You can find the source code on our Github Page.

Related Posts