Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a deep unmodifiable collection?

I often make a collection field unmodifiable before returning it from a getter method:

private List<X> _xs;
....
List<X> getXs(){
  return Collections.unmodifiableList(_xs);
}

But I can't think of a convenient way of doing that if the X above is itself a List:

private List<List<Y>> _yLists;
.....
List<List<Y>> getYLists() {
  return Collections.unmodifiableList(_yLists);
}

The problem in the above is of course that though the client cannot modify the List of lists, it can add/delete Y objects from the embedded lists.

Any thoughts?

like image 723
Miserable Variable Avatar asked Jan 06 '09 09:01

Miserable Variable


People also ask

Is Unmodifiable list immutable?

If you create a List and pass it to the Collections. unmodifiableList method, then you get an unmodifiable view. The underlying list is still modifiable, and modifications to it are visible through the List that is returned, so it is not actually immutable.

Is unmodifiableMap thread safe?

unmodifiableMap(deliverersMod); as well as the preceding operations where the map is populated. So your code is thread safe and your getDeliverers method will return a result based on the latest version of your map.

What is an unmodifiable set?

unmodifiableSet( new HashSet<String>() ); creates an instance of a Set which will throw UnsupportedOperationException if one attempts to call fixed. add() or fixed. remove() , for example - the object itself will protect its internal state and prevent it from being modified.


2 Answers

The best I could come up with uses ForwardingList from Google Collections. Comments are welcome.

private static <T> List<List<T>> unmodifiableList2(final List<List<T>> input) {
    return Collections.unmodifiableList(new ForwardingList<List<T>>() {
        @Override protected List<List<T>> delegate() {
            return Collections.unmodifiableList(input);
        }
        @Override public List<T> get(int index) {
            return Collections.unmodifiableList(delegate().get(index));
        }
    });
}
like image 141
Miserable Variable Avatar answered Sep 28 '22 15:09

Miserable Variable


unfortunately, there is no easy way to get deep const-ness in java. you would have to hack around it by always making sure that the list inside the list is also unmodifiable.

i'd be interested too to know any elegant solution.

like image 29
Chii Avatar answered Sep 28 '22 15:09

Chii