Here's a List with a size limit, based on Guava's ForwardingList
:
A list which forwards all its method
calls to another list. Subclasses
should override one or more methods to
modify the behavior of the backing
list as desired per the decorator
pattern.
Guava has base classes like this for all JDK-5 Collection types. Each of them fulfills the same purpose: making it easy to add value, while delegating all default functionality to the underlying collection.
public class LimitingList<E> extends ForwardingList<E> {
private final class LimitingListIterator extends ForwardingListIterator<E> {
private final ListIterator<E> innerListIterator;
private LimitingListIterator(final ListIterator<E> innerListIterator) {
this.innerListIterator = innerListIterator;
}
/**
* {@inheritDoc}
*/
@Override
public void add(final E element) {
if (inner.size() < maxSize)
innerListIterator.add(element);
else
throw new IndexOutOfBoundsException();
}
@Override
protected ListIterator<E> delegate() {
return innerListIterator;
}
}
public LimitingList(final int maxSize) {
this(new ArrayList<E>(), maxSize);
}
public LimitingList(final List<E> inner, final int maxSize) {
super();
this.inner = inner;
this.maxSize = maxSize;
}
@Override
public boolean addAll(final Collection<? extends E> collection) {
boolean changed = false;
for (final E item : collection) {
final boolean tmpChanged = add(item);
changed = changed || tmpChanged;
if (!tmpChanged)
break;
}
return changed;
}
@Override
public boolean add(final E e) {
if (inner.size() < maxSize)
return super.add(e);
else
return false;
}
@Override
public ListIterator<E> listIterator() {
return new LimitingListIterator(inner.listIterator());
}
@Override
public void add(final int index, final E element) {
throw new UnsupportedOperationException();
}
@Override
public boolean addAll(final int index, final Collection<? extends E> elements) {
throw new UnsupportedOperationException();
}
@Override
public ListIterator<E> listIterator(final int index) {
return new LimitingListIterator(inner.listIterator(index));
}
private final int maxSize;
private final List<E> inner;
@Override
protected List<E> delegate() {
return inner;
}
}
It delegates all real functionality to an underlying list, which is an ArrayList per default (single argument constructor), but you can also supply (two argument constructor)