Writing or creating immutable collections in Java is becoming popular day by day, because of concurrency and multithreading advantage provided by immutable objects. Immutable objects offers several benefits over conventional mutable object, especially while creating concurrent Java application. Immutable object not only guarantees safe publication of object’s state, but also can be shared among other threads without any external synchronization. Making instance variable final will not work as collection is storing reference of objects:
final List<String> finallist = new ArrayList(){{add("123");add("234");add("345");}};
finallist.add("345");
java.util.Collection and java.util.Arrays Classes provides way to create Immutable Collection which can be shared between threads or methods. Lets take an example to understand this concept.
Below Java program has two parts
(1)First we are creating array of String objects and converting that array to ArrayList (which is considered as growable array) using java.util.Arrays class's Arrays.asList () method. -- Passing the arrayList to one method which tries to update the arrayList.
(2) In second section we are creating with one ArrayList and converting to unmodifiableList (Collections class has other methods as well for Set, Map, sortedSet, TreeMap and Collection )
package arraylist;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class ImmutableArrayList {
public static void main(String[] args) {
String[] fooArray = {"one", "two", "three"};
List<String> myList = Arrays.asList(fooArray);
List<String> myUpdatedList = updateMyList(myList);
System.out.println(myUpdatedList);
//OtherWay to create Immutable List
List<String> list = new ArrayList(){{add("123");add("234");add("345");}};
System.out.println("Elements of ArrayList: " + list);
List<String> immutableCol = Collections.unmodifiableList(list);
updateMyList(immutableCol);
}
public static List<String> updateMyList(List<String> myList){
try{
myList.add("four");
myList.remove("one");
}catch(UnsupportedOperationException e){
e.printStackTrace();
System.out.println("Exception while updating List- Returning same list");
}finally{
return myList;
}
}
}
Output of program:
java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at arraylist.ImmutableArrayList.updateMyList(ImmutableArrayList.java:28)
at arraylist.ImmutableArrayList.main(ImmutableArrayList.java:15)
Exception while updating List- Returning same list
[one, two, three]
Elements of ArrayList: [123, 234, 345]
java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableCollection.add(Collections.java:1075)
at arraylist.ImmutableArrayList.updateMyList(ImmutableArrayList.java:28)
at arraylist.ImmutableArrayList.main(ImmutableArrayList.java:22)
Exception while updating List- Returning same list
Quick fix for this is initialize a mutable list passing the immutable list returned by the method:
List<String> fooList= new ArrayList<String>(Arrays.asList(fooArray));