Immutable Set in Java

We have learned about Set and HashSet in java. A HashSet is not thread-safe by default, if we want to use it in a multithreading environment we can use an Immutable set. In this tutorial, we will learn what is immutable Set and how to make an immutable Set. let’s understand why we need it.

Here is the table content of the article will we will cover this topic.
1. What is an immutable Set?
2. Need of the immutable set in java?
3. How does it work?
4. How to Creating Immutable Set

5. The important concepts of the Immutable Set?

1. What is an immutable Set?

As you know, an immutable object will not change after the declaration although we can change its properties. The immutable objects are thread-safe because multiple threads can read them but can’t change the object’s state. If you are getting confused in an immutable object you should learn why String is immutable and how does it work?

In the same manner, We can create an immutable set that will be thread-safe. The immutable Set can have a collection of objects like HashSet but we can’t modify the objects of the immutable set. If we try to add or remove any object in immutable set it throws UnsupportedOperationException.

2. Need of the immutable set in java?

We can use the Immutable set when we have to work in a multithreading environment. As we have already discussed the immutable set is ready only. Because if the user tries to modify(add or remove from Set) the immutable Set then the compiler will throw UnsupportedOperationException. The most common use case of an immutable set is in a multi-threaded environment. Multiple threads can share immutable set data without worrying about synchronization.

3. How does it work?

An immutable set, the user can modify the object properties but not the object.
Let’s say we have an immutable set that stores the three students’ records. Each student has a name, class, roll, etc.
You can change the name of the student, class name, and roll no. But you can’t change the number of students in an immutable set (add or delete student).

java immutable set
import java.util.Iterator;
import java.util.Set;
class Student 
{
	int rollNo;
	String name; 
	String className;
	public Student(int rollNo, String className, String name) 
	{
		this.rollNo = rollNo;
		this.name = name;
		this.className = className;
	}
	public int getRollNo() {
		return rollNo;
	}
	public void setRollNo(int rollNo) {
		this.rollNo = rollNo;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getClassName() {
		return className;
	}
	public void setClassName(String className) {
		this.className = className;
	}
}

public class ImmutableSetExample
{
	public static void main(String[] args) 
	{
		Student student1 = new Student(1, "MCA", "Ram");
		Student student2 = new Student(2, "BCA", "John");
		Student student3 = new Student(3, "BCA", "Krishna");
		
		//creating Set from existing HashSet
		Set<Student> immutableSet = Set.of(student1, student2, student3); 
		
		for(Student s : immutableSet)
		{
			System.out.println("Rollno :" + s.getRollNo());
			System.out.println("Class Name :" + s.getClassName());
			System.out.println("Name :" + s.getName());
		}
		// Changing the class Name of rollno 2
		Iterator<Student> it = immutableSet.iterator();
		while(it.hasNext())
		{
			Student s = it.next();
			if(s.getRollNo() == 2)
				s.setClassName("MCA");
		}
        
		Iterator<Student> it1 = immutableSet.iterator();
		while(it1.hasNext())
		{
			Student s = it1.next();
			if(s.getRollNo() == 2)
				System.out.println("Name Changed of class:"+s.getClassName());
		}
	}
}

Output: Rollno :1
Class Name :Ram
Name :MCA
Rollno :3
Class Name :Krishna
Name :BCA
Rollno :2
Class Name :John
Name :BCA
Name Changed of class:MCA

4. How to Creating Immutable Set

You can create an immutable Set in various ways.

1. By use of copyOf() method

ImmutableSet<E> copyOf(Collection<? extends E> elements)

It returns an immutable set that contains all the elements of the given list/collection. It will throw NullPointerException if any element is null in the given collection.

import com.google.common.collect.ImmutableSet;

import java.util.*; 

class ExampleOfImmutableSet { 

	// Function to create ImmutableList from List 
	public static void main(String[] args) 
	{
	    // Create Immutable Set using copyOf() 
		ImmutableSet<String> immutableSet = 
				ImmutableSet.copyOf(Arrays.asList("Learning", "Web", "Site")); 
		
		
		List<String> list = new ArrayList<String>(Arrays.asList("Java", "Goal", "com")); 
		
       // Create Immutable Set using copyOf() from existing set 
		ImmutableSet<String> immutableSet1 = 
				ImmutableSet.copyOf(list); 
      
      // Print the Immutable Set
		System.out.println(immutableSet); 
      // Print the Immutable Set
		System.out.println(immutableSet1); 
	}
	
}

Output: [Learning, Web, Site]
[Java, Goal, com]

2. By use of() method we can create ImmutableSet

ImmutableSet<E> of() 

It returns an immutable set containing the given element.

import com.google.common.collect.ImmutableSet; 

class ExampleOfImmutableSet 
{ 
	// Function to create ImmutableList from List 
	public static void main(String[] args) 
	{
		// non-empty immutable set 
        ImmutableSet<String> immutableSet = ImmutableSet.of("Java", "Goal", "com"); 
           
        // Print the element from Set
        System.out.println(immutableSet);  
    }
}

Output: [Java, Goal, com]

3. By Using Of() method in Java 9 Factory

Please Note: This program can run only in Java 9. You need a Java 9 compiler to run them.

import java.util.Set; 

public class ImmutableSetExample
{
	public static void main(String[] args) 
	{
		// non-empty immutable set 
        Set<String> immutableSet = Set.of("Java", "Goal", "com"); 
  
        // Let's print the Set 
        System.out.println(immutableSet); }
}

Output: [Java, Goal, com]

4. By Collections.unmodifiableSet() method

First of all, create a HashSet object and initialize it with some values. After that, wrap it up with Collections.unmodifiableSet()

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class ImmutableSetExample
{
	public static void main(String[] args) 
	{
		Set<String> set = new HashSet<>();
		set.add("Java");
		set.add("Goal");
		set.add("Com");
		
		Set<String> unmodifiableSet = Collections.unmodifiableSet(set);
        
		// Let's print the list 
        System.out.println(unmodifiableSet);
	}
}

Output: [Com, Java, Goal]

5. The important concepts of the Immutable Set

  1. If a user tries to modify the immutable Set(add or delete elements in the Set) then UnsupportedOperationException is thrown. Because you can’t modify immutable Set.
import java.util.List;
import java.util.Set;

public class ImmutableSetExample
{
	public static void main(String[] args) 
	{
		Set<String> immutableSet = Set.of("Java", "Goal", "com"); 
        // Let's print the Set 
        System.out.println(immutableSet);
        
        //try to add the element in Set
        immutableSet.remove("Hello");
	}
}

Output: [Java, Goal, com]
Exception in thread “main” java.lang.UnsupportedOperationException at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:71) at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.remove(ImmutableCollections.java:78) at Create.ImmutableSetExample.main(ImmutableSetExample.java:15)

2. An Immutable Set does not allow any null element. If a user tries to add null in Immutable Set the compiler will throw UnsupportedOperationException.

import java.util.List;

public class ImmutableSetExample
{
	public static void main(String[] args) 
	{
		List<String> immutableList = List.of("Java", "Goal", "Com"); 
        // Let's print the list 
        System.out.println(immutableList);
        
        //try to add the element in list
        immutableList.add(null);
	}
}

Output: [Java, Goal, Com]
Exception in thread “main” java.lang.UnsupportedOperationException at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:71) at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add(ImmutableCollections.java:75) at Create.ImmutableSetExample.main(ImmutableSetExample.java:14)

3. If a user tries to create an Immutable Set with a null element, then the compiler will throw  NullPointerException. 

import java.util.List;

public class ImmutableSetExample
{
	public static void main(String[] args) 
	{
		List<String> immutableList = List.of("Java", "Goal", null); 
        // Let's print the list 
        System.out.println(immutableList);
        
        
	}
}

Output: Exception in thread “main” java.lang.NullPointerException at java.base/java.util.Objects.requireNonNull(Objects.java:221)    at java.base/java.util.ImmutableCollections$ListN.<init>(ImmutableCollections.java:423) at java.base/java.util.List.of(List.java:842) at Create.ImmutableSetExample.main(ImmutableSetExample.java:9)

If the user is creating an Immutable Set from an existing Set and change the existing Set, then the changes don’t reflect on Immutable Set. Because we have created a copy of the existing Set.

Leave a Comment