Protect ArrayList from write access

Consider the following class:

public class Cars extends Observable{

    private ArrayList<String> carList = new ArrayList<String>();

    public void addToCarList(String car){
        // ...
        hasChanged();
        notifyObservers();
    }

    public void removeFromCarList(String car){
        // ...
        hasChanged();
        notifyObservers();
    }

    public ArrayList<String> getCarList() {
        return carList;
    }    
}

As you can see, every time the carList is changed, I want to notify the Observers. If someone does getCarList().add(...);, this is circumvented.

How can I give read access to the carList (for iterating over it etc.) but prevent write access to it except for the special methods addToCarList and removeFromCarList?

I thought about this:

public ArrayList<String> getCarList() {
    return (ArrayList<String>)carList.clone();
}

but someone using my class would, when adding something to the clone of carList, not be informed that that's not the way it's meant to be done.

Jon Skeet
people
quotationmark

You can return an unmodifiable view of it, changing the return type to List<String> instead of ArrayList<String>:

public List<String> getCars() {
    return Collections.unmodifiableList(carList);
}

Note that as Collections.unmodifiableList does only provide a view, the caller will still see any other changes that are made via addToCarList and removeFromCarList (which I'd rename to addCar and removeCar, probably). Is that what you want?

Any mutating operations on the returned view will result in an UnsupportedOperationException.

people

See more on this question at Stackoverflow