Hello, everyone!

My next proposal for the "Collections" utility class is a bunch of methods 
(similar to unmodifiable[...])
which would return not an unmodifiable List|Map|Set, but a constant-sized one.
That is, all methods which get|set|... elements would work as earlier, but 
methods which
would alter the size of the underlying collection (add|put|remove|retain|...) 
would throw UnsupportedOperationException.

So the new logic hoerarchy would be:
1) Unmodifiable[something] -- very strict
2) ConstantSized[something] -- less strict
3) [Usual collections]

A constant-sized-list would be nearly same as an unmodifiable-list, with the 
exception that set(int index)
would be allowed.
A constant-sized-map would be nearly same as an unmodifiable-map, with the 
exception that put(K key, V value) on EXISTING
keys would be allowed.

I have no opinion of the usability of this proposal for Maps or Sets (it could 
make sense, but it could make none).
But I am very sure, that for Lists it is very useful.

What do you think of such a proposal? Not too specific? I, for myself, need 
such constant-sized collections often.

( I don't know about the name. ConstantSized[...]? NonResizable[...]? 
Sealed[...]? )

Please take a look at a proposal for a ConstantSizedList:

import java.util.*;

/**
 * Wrapps around an ArrayList and prevents all resizing methods by throwing
 * an UnsupportedOperationException. The underlying ArrayList still may be 
changed.
 *
 * The underlying ArrayList is sealed by following means:
 * - methods which return an iterator use Collections.unmodifiableList(...);
 * - adding, clearing, removing, retaining methods throw 
UnsupportedOperationException;
 * - all other methods are delegated to the underlying ArrayList.
 */
public final class ConstantSizeArrayList<T>
                implements List<T>, RandomAccess, Cloneable {

        private final static RuntimeException ex =
                        new 
UnsupportedOperationException(ConstantSizeArrayList.class
                        + " doesn't allow methods which resize the underlying 
collection");

        private final ArrayList<T> underlying;

        public ConstantSizeArrayList(ArrayList<T> underlying) {
                this.underlying = underlying;
                underlying.trimToSize();
        }

        @Override
        public String toString() {
                return underlying.toString();
        }

        @Override
        public boolean containsAll(Collection<?> c) {
                return underlying.containsAll(c);
        }

        @Override
        public int hashCode() {
                return underlying.hashCode();
        }

        @Override
        public boolean equals(Object o) {
                return underlying.equals(o);
        }

        @Override
        public <T> T[] toArray(T[] a) {
                return underlying.toArray(a);
        }

        @Override
        public Object[] toArray() {
                return underlying.toArray();
        }

        @Override
        public List<T> subList(int fromIndex, int toIndex) {
                return underlying.subList(fromIndex, toIndex);
        }

        @Override
        public int size() {
                return underlying.size();
        }

        @Override
        public T set(int index, T element) {
                return underlying.set(index, element);
        }

        @Override
        public Iterator<T> iterator() {
                return Collections.unmodifiableList(underlying).iterator();
        }

        @Override
        public ListIterator<T> listIterator() {
                return Collections.unmodifiableList(underlying).listIterator();
        }

        @Override
        public ListIterator<T> listIterator(int index) {
                return 
Collections.unmodifiableList(underlying).listIterator(index);
        }

        @Override
        public int lastIndexOf(Object o) {
                return underlying.lastIndexOf(o);
        }

        @Override
        public boolean isEmpty() {
                return underlying.isEmpty();
        }

        @Override
        public int indexOf(Object o) {
                return underlying.indexOf(o);
        }

        @Override
        public T get(int index) {
                return underlying.get(index);
        }

        @Override
        @SuppressWarnings("element-type-mismatch")
        public boolean contains(Object o) {
                return underlying.contains(o);
        }

        // TODO delegating clone: is that OK?
        @Override
        public Object clone() {
                return underlying.clone();
        }

        @Override
        public void clear() {
                throw ex;
        }

        @Override
        public boolean addAll(int index, Collection<? extends T> c) {
                throw ex;
        }

        @Override
        public boolean addAll(Collection<? extends T> c) {
                throw ex;
        }

        @Override
        public void add(int index, T element) {
                throw ex;
        }

        @Override
        public boolean add(T e) {
                throw ex;
        }

        @Override
        public boolean retainAll(Collection<?> c) {
                throw ex;
        }

        @Override
        public boolean removeAll(Collection<?> c) {
                throw ex;
        }

        @Override
        public boolean remove(Object o) {
                throw ex;
        }

        @Override
        public T remove(int index) {
                throw ex;
        }

}



Best regards,
Ivan G Shevchenko

Reply via email to