How to create Immutable List in java?

user4768611 picture user4768611 · May 20, 2015 · Viewed 70.4k times · Source

I need to convert mutable list object to immutable list. What is the possible way in java?

public void action() {
    List<MutableClass> mutableList = Arrays.asList(new MutableClass("san", "UK", 21), new MutableClass("peter", "US", 34));
    List<MutableClass> immutableList = immutateList(mutableList);
}

public List<MutableClass> immutateList(List<MutableClass> mutableList){
    //some code here to make this beanList immutable
    //ie. objects and size of beanList should not be change.
    //ie. we cant add new object here.
    //ie. we cant remove or change existing one.
}

MutableClass

final class MutableClass {
    final String name;    
    final String address;
    final int age;
    MutableClass(String name, String address, int age) {
        this.name = name;
        this.address = address;
        this.age = age;
    }
}

Answer

aioobe picture aioobe · May 20, 2015

Once your beanList has been initialized, you can do

beanList = Collections.unmodifiableList(beanList);

to make it unmodifiable. (See Immutable vs Unmodifiable collection)

If you have both internal methods that should be able to modify the list, and public methods that should not allow modification, I'd suggest you do

// public facing method where clients should not be able to modify list    
public List<Bean> getImmutableList(int size) {
    return Collections.unmodifiableList(getMutableList(size));
}

// private internal method (to be used from main in your case)
private List<Bean> getMutableList(int size) {
    List<Bean> beanList = new ArrayList<Bean>();
    int i = 0;

    while(i < size) {
        Bean bean = new Bean("name" + i, "address" + i, i + 18);
        beanList.add(bean);
        i++;
    }
    return beanList;
}

(Your Bean objects already seem immutable.)


As a side-note: If you happen to be using Java 8+, your getMutableList can be expressed as follows:

return IntStream.range(0,  size)
                .mapToObj(i -> new Bean("name" + i, "address" + i, i + 18))
                .collect(Collectors.toCollection(ArrayList::new));