A List is considered unmodifiable if elements cannot be added, removed, or replaced from the list once the unmodifiable instance of a List is created. In this post we’ll see how Unmodifiable list was created before Java 9 and how it can be created Java 9 onward using Immutable List Static Factory Methods.
Creating Unmodifiable list before Java 9
Before Java 8, in order to create unmodifiable list Collections.unmodifiableList()
method was used.
- Collections.unmodifiableList(List<? extends T> list)- Returns an unmodifiable view of the specified list. Note that the list underneath can still be modified.
public class UnmodifiedList { public static void main(String[] args) { List<String> alphaList = new ArrayList<>(); alphaList.add("a"); alphaList.add("b"); alphaList.add("c"); alphaList.add("d"); //List<String> alphaList = Arrays.asList("a", "b", "c", "d"); List<String> aList = Collections.unmodifiableList(alphaList); alphaList.add("e"); System.out.println("alphaList- " + alphaList); aList.add("f"); } }
Output
alphaList- [a, b, c, d, e] Exception in thread "main" java.lang.UnsupportedOperationException at java.base/java.util.Collections$UnmodifiableCollection.add(Collections.java:1058) at org.netjs.Programs.UnmodifiedList.main(UnmodifiedList.java:20)
As you can see alphaList which is used to create unmodifiable list can still be modified though changing the unmodifiable list results in UnsupportedOperationException.
By using Arrays.asList to create list you can ensure that methods that change the size of the list can’t be called on the returned list.
public class UnmodifiedList { public static void main(String[] args) { List<String> alphaList = Arrays.asList("a", "b", "c", "d"); List<String> aList = Collections.unmodifiableList(alphaList); alphaList.add("e"); System.out.println("alphaList- " + alphaList); aList.add("f"); } }
Output
Exception in thread "main" java.lang.UnsupportedOperationException at java.base/java.util.AbstractList.add(AbstractList.java:153) at java.base/java.util.AbstractList.add(AbstractList.java:111) at org.netjs.Programs.UnmodifiedList.main(UnmodifiedList.java:13)
As you can see now the original list itself can’t call any size changing operation.
Creating Unmodifiable list in Java 9
The List.of
(added in Java 9) and List.copyOf
(added in Java 10) static factory methods provide a convenient way to create unmodifiable lists.
The List instances created by these methods have the following characteristics-
- The collections returned by the convenience factory methods added in JDK 9 are conventionally immutable. Elements cannot be added, removed, or replaced from such a list. Elements cannot be added, removed, or replaced from such a list. Calling any mutator method on the List will always cause UnsupportedOperationException to be thrown.
- If the elements with in the list themselves are mutable, this may cause the List's contents to appear to change.
- Such lists can't be created with null elements any such attempt result in NullPointerException.
- Unmodifiable lists are serializable if all elements are serializable.
- 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.
List.of() method in Java
List.of() method static factory method is a convenient way to create unmodifiable lists Java 9 onward. This method has both fixed-argument form and varargs form. Fixed-argument form overloads up to 10 elements and the form of these method is as follows.
List.of(E e1)- Returns an unmodifiable list containing one element. .. .. List.of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)- Returns an unmodifiable list containing nine elements. List.of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)- Returns an unmodifiable list containing ten elements.
varargs form
- List.of(E... elements)- Returns an unmodifiable list containing an arbitrary number of elements.
List.of() method Java example
public class UnmodifiedList { public static void main(String[] args) { List<String> alphaList = List.of("a", "b", "c", "d"); System.out.println("alphaList- " + alphaList); // raises error alphaList.add("e"); } }
Output
alphaList- [a, b, c, d] 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 org.netjs.Programs.UnmodifiedList.main(UnmodifiedList.java:10)
List.copyOf() method in Java
If you want to create an unmodifiable List using an existing collection then you can use copyOf() method.
- List.copyOf(Collection<? extends E> coll)- Returns an unmodifiable List containing the elements of the given Collection, in its iteration order. The given Collection must not be null, and it must not contain any null elements. If the given Collection is subsequently modified, the returned List will not reflect such modifications.
List.copyOf() method Java example
public class UnmodifiedList { public static void main(String[] args) { List<String> alphaList = new ArrayList<>(); alphaList.add("a"); alphaList.add("b"); alphaList.add("c"); alphaList.add("d"); List<String> aList = List.copyOf(alphaList); alphaList.add("e"); System.out.println("alphaList- " + alphaList); System.out.println("aList- " + aList); } }
Output
alphaList- [a, b, c, d, e] aList- [a, b, c, d]
As you can see even if the original collection is modified the returned unmodifiable list doesn’t reflect such modification.
That's all for this topic Unmodifiable or Immutable List in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!
Related Topics
You may also like-
public class UnmodifiedList {
ReplyDeletepublic static void main(String[] args) {
List alphaList = Arrays.asList("a", "b", "c", "d");
List aList = Collections.unmodifiableList(alphaList);
alphaList.add("e");
System.out.println("alphaList- " + alphaList);
aList.add("f");
}
}
in above exmple alphaList list object itself immutable one, so again no need to pass this alphaList object to Collections.unmodifiableList(). so comment it out
No they are still different- Arrays.asList() returns a fixed-size list meaning operations that would change the size of the returned list are not permitted but you can still modify the existing element.
DeleteCollections.unmodifiableList() method returns well an unmodifiable list.
Run this code to dispel any doubts.
public class UnmodifiedList {
public static void main(String[] args) {
List alphaList = Arrays.asList("a", "b", "c", "d");
List aList = Collections.unmodifiableList(alphaList);
alphaList.set(3, "e");
System.out.println("alphaList- " + alphaList);
aList.set(3, "f");
System.out.println("aList- " + aList);
}
}