Zeeshan
Zeeshan

Reputation: 12421

How to prevent an ArrayList to be Structually Modified?

I am mapping a Table... say Employee to an ArrayList<Employee> which is a class level variable and I will be using it in multiple places instead of hitting the Data Base each time.

I want to keep it as read only, ie. no one can add or remove an element from the ArrayList once populated.

Can someone suggest a way to achieve this?

Edit: On modification I want some kind of Exception to be thrown.

Thanks in advance

Upvotes: 0

Views: 632

Answers (3)

Zeeshan
Zeeshan

Reputation: 12421

You can provide a getter which will return a copy of the existing list.

Use a copy constructor for that:

class Employee {
  private String id;
  ...

  public Employee(Employee other) {
    this.id = other.id; 
    ...
  }
}



List<Employee> getEmployeeData()
{
    //create a new list using the existing one via copy constructor
    return "Newly constructed list";
}

Other approach which comes to my mind is to get a private Iterator on the List after populating it, so if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. But note that the fail-fast behavior of an iterator cannot be guaranteed.

From javaDoc:

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future. Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness

Upvotes: 0

nanofarad
nanofarad

Reputation: 41281

You can use Collections.unmodifiableList. It will pass through reads to the backing list, so any updates to the backing (original) list will affect the immutable view that other classes see.

If you want an unmodifiable list that is not updated when the master list is updated, you'll need to call a copy constructor:

Collections.unmodifiableList(new ArrayList<Employee>(masterList));

Guava's immutable list is also an option in this case.

Upvotes: 5

NimChimpsky
NimChimpsky

Reputation: 47290

unmodifiable list is what you want here is the doc,and guava has an immutable list

Upvotes: 1

Related Questions