March 12, 2022

Java Immutable Set With Examples

In Java 9 new static factory method has been added to create an immutable Set in Java. In this article we’ll see an example of creating immutable set using factory method and how it makes it more convenient than the previous option of using Collections.unmodifiableSet().

You can not remove or add elements from an immutable Set. Calling any mutator method on the Set will always cause UnsupportedOperationException to be thrown.

Creating immutable or unmodifiable set before Java 9

Before Java 9, Collections.unmodifiableSet() method was used to create an immutable set. One thing to note with this method is that original set can still be modified.

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

public class ImmutSet {
  public static void main(String[] args) {
    Set<String> numSet = new HashSet<>();
    numSet.add("1");
    numSet.add("2");
    numSet.add("3");
    numSet.add("4");
    Set<String> iSet = Collections.unmodifiableSet(numSet);
    numSet.add("5");
    System.out.println("Numbers- " + numSet);
    // Throws Exception as this set is an unmodifiable view
    iSet.add("6");
  }
}
Output
Numbers- [1, 2, 3, 4, 5]

Exception in thread "main" 
java.lang.UnsupportedOperationException
	at java.base/java.util.Collections$UnmodifiableCollection.add(Collections.java:1058)
	at com.knpcode.proj.Programs.ImmutSet.main(ImmutSet.java:19)

As you can see, original set (numSet) can still be modified. Same thing can be done in less verbose manner as given below-

public class ImmutSet {
  public static void main(String[] args) {
    Set<String> numSet = new HashSet<>(Arrays.asList("1", "2", "3", "4"));
    numSet = Collections.unmodifiableSet(numSet);
  }
}

Creating Immutable Set Java 9 onward

Java 9 onward there are two convenient static factory methods that can be used to create immutable Set.

  1. Set.of() (Added in Java 9)
  2. Set.copyOf() (Added in Java 10)

The Set instances created by these methods have the following characteristics:

  • They are unmodifiable. Elements cannot be added or removed. Calling any mutator method on the Set will always cause UnsupportedOperationException to be thrown. However, if the contained elements are themselves mutable, this may cause the Set to behave inconsistently or its contents to appear to change.
  • These methods disallow null elements. Attempts to create them with null elements result in NullPointerException.
  • They are serializable if all elements are serializable.
  • They reject duplicate elements at creation time. Duplicate elements passed to a static factory method result in IllegalArgumentException.
  • The iteration order of set elements is unspecified and is subject to change.
Set.of() method example

Set.of() method has many overloaded forms giving you option to create set from 0 to 10 elements.

of()- Returns an unmodifiable set containing zero elements. of(E e1)- Returns an unmodifiable set containing one element. of(E e1, E e2)- Returns an unmodifiable set containing two elements. .. .. of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)- Returns an unmodifiable set containing nine elements. of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)- Returns an unmodifiable set containing ten elements.

There is also a varargs form

of(E... elements)- Returns an unmodifiable set containing an arbitrary number of elements.

import java.util.Set;

public class ImmutSet {
  public static void main(String[] args) {
    Set<String> numSet = Set.of("1", "2", "3", "4");
    System.out.println("numSet- " + numSet);
    //Throws exception as the Set is immutable
    numSet.add("5");
  }
}
Output
numSet- [3, 4, 1, 2]
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:72)
	at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add(ImmutableCollections.java:76)
	at com.knpcode.proj.Programs.ImmutSet.main(ImmutSet.java:10)
Set.copyOf() method example

This method can be used if you want to create an Immutable set from any given Collection. The given Collection must not be null, and it must not contain any null elements. If the given Collection is subsequently modified, the returned Set will not reflect such modifications.

public class ImmutSet {
  public static void main(String[] args) {
    Set<String> numSet = new HashSet<>();
    numSet.add("1");
    numSet.add("2");
    numSet.add("3");
    numSet.add("4");
    System.out.println("numSet- " + numSet);
    Set<String> iSet = Set.copyOf(numSet);
    System.out.println("Immutable Set- " + iSet);

    numSet.add("5");
    System.out.println("numSet after modification- " + numSet);
    System.out.println("Immutable Set- " + iSet);
  }
}
Output
numSet- [1, 2, 3, 4]
Immutable Set- [1, 2, 3, 4]
numSet after modification- [1, 2, 3, 4, 5]
Immutable Set- [1, 2, 3, 4]

As you can see when the Collection that is used to create the Immutable set is modified that change is not reflected to the Set.

That's all for the topic Java Immutable Set With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment