Sunday, 20 February 2011

Returning immutable collections

Many times it is desirable to return an internal collection object to consumers of your class.

For example:

class Foo {
List _internalObjects = new ArrayList();

List getList() {
return _internalObjects;
}
}


The method above works, but has a draw back. The elements of your internalObjects list are now mutable outside your control. In C++ you might try to return const& instead to get around this problem, but how do you solve this in Java?

The first approach might be to return a copy. e.g:
class Foo {
List _internalObjects = new ArrayList();

List getList() {
List copy = new ArrayList();
copy.addAll(_internalObjects);
return copy;
}
}


This has the desired effect but with a couple of disadvantages. First you had to perform the copy which could be a performance bottleneck. Second the consumer may no longer point to the same objects if you modify your internalObject class.

The best way, that I know of, to do this is as follows:

class Foo {
final List _internalObjects = new ArrayList();

List getList() {

return new AbstractList() {
@Override
public Object get(int index)
{
return _internalObjects.get(index);
}
@Override
public int size()
{
return _internalObjects.size();
}
};
}
}


The returned list still points to internal list, but is read only. Also, just to be pedantic, I've marked the list as final which means the reference will never change which is more correct for this example.

No comments:

Post a Comment