amudhan3093
amudhan3093

Reputation: 750

Convert an ArrayList to an unmodifiable ArrayList

I'm trying to get a unmodifiable ArrayList to a final variable EX_FIELDS. exList is an existing ArrayList object.

EX_FIELDS = (ArrayList<String>) Collections.unmodifiableList(exList);

This code is present in a static block.When the class loads, I get the following error.

java.lang.ClassCastException: java.util.Collections$UnmodifiableRandomAccessList cannot be cast to java.util.ArrayList

I need to use the EX_FIELDS to support random access.Is there any other way to accomplish it?Thanks for any help in advance

Upvotes: 5

Views: 11405

Answers (4)

Sugat Shivsharan
Sugat Shivsharan

Reputation: 595

The reason error occurs is Collections.unmodifiablelist(exList) returns a List, what you are trying to do is

ArrayList<T> EX_FIELDS=(ArrayList<T>)List<T>();

List is an interface and cannot be instantiated. The EX_FIELDS variable can only store ArrayList object, hence the classcast exception error.

A proper way to do this is :

List<String> EX_FIELDS=Collections.unmodifiablelist(exList)

Upvotes: 0

GhostCat
GhostCat

Reputation: 140457

The other answers are correct, but missing a crucial point: an unmodifiable list created this way can still be modified.

This call to the Collections class creates awrapper object that wraps around the provided exList argument.

In other words: when exList changes, your wrapped list changes as well.

So when you want to be really sure, you have to first create a new temporary list to which you add all entries of exList; and then you use that Collections method to wrap around that temporary copy.

Upvotes: 0

Stephen P
Stephen P

Reputation: 14800

You get a ClassCastException because Collections.unmodifiableList() doesn't return an ArrayList, it returns a List<T> (interface) which can be any backing class that implements the List interface. As you can see from the exception, it is actually returning an UnmodifiableRandomAccessList.

When you create the variable EX_FIELDS you should declare it like

List<String> EX_FIELDS = new ArrayList<>();

That is, EX_FIELDS is a List and you have chosen an ArrayList for the actual instance. Later on you'll do

EX_FIELDS = Collections.unmodifiableList(exList);

unmodifiableList() returns a List, but you don't care what kind it actually is, as long as it conforms to the List interface.

Upvotes: 3

Louis Wasserman
Louis Wasserman

Reputation: 198123

EX_FIELDS should have type List<String>, not ArrayList<String>, and you shouldn't need to do any cast: you should just write

EX_FIELDS = Collections.unmodifiableList(exList);

This is one instance of the much more general rule that you should program to the interface, not the implementation.

Upvotes: 14

Related Questions