java:列表包装器,其中允许get()/set(),但不允许添加/删除

java:列表包装器,其中允许get()/set(),但不允许添加/删除,java,list,Java,List,我需要用一些类包装一个列表,这些类允许设置/获取调用,但不允许添加/删除调用,因此列表保持固定长度。我想下面有一个瘦包装器类可以工作,但我不是100%肯定 我错过了什么明显的东西吗 import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; class RestrictedListWrapper<T> implements

我需要用一些类包装一个列表,这些类允许设置/获取调用,但不允许添加/删除调用,因此列表保持固定长度。我想下面有一个瘦包装器类可以工作,但我不是100%肯定

我错过了什么明显的东西吗

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

class RestrictedListWrapper<T> implements List<T>
{
    static <T> T fail() throws UnsupportedOperationException
    {
        throw new UnsupportedOperationException();
    }   

    static private class IteratorWrapper<T> implements ListIterator<T>
    {
        final private ListIterator<T> iter;

        private IteratorWrapper(ListIterator<T> iter) { this.iter = iter; }
        static public <T> RestrictedListWrapper.IteratorWrapper<T> wrap(ListIterator<T> target) { 
            return new RestrictedListWrapper.IteratorWrapper<T>(target); 
        }
        @Override public void add(T e) { fail(); }
        @Override public boolean hasNext() { return this.iter.hasNext(); }
        @Override public boolean hasPrevious() { return this.iter.hasPrevious(); }
        @Override public T next() { return this.iter.next(); }
        @Override public int nextIndex() { return this.iter.nextIndex(); }
        @Override public T previous() { return this.iter.previous(); }
        @Override public int previousIndex() { return this.iter.previousIndex(); }
        @Override public void remove() { fail(); }
        @Override public void set(T e) { this.iter.set(e); }
    }       

    final private List<T> list;

    private RestrictedListWrapper(List<T> list) {
        this.list = list;
    }
    static public <T> RestrictedListWrapper<T> wrap(List<T> target) {
        return new RestrictedListWrapper<T>(target);
    }
    @Override public boolean add(T arg0) { return fail();  } 
    @Override public void add(int index, T element) { fail(); }
    @Override public boolean addAll(Collection<? extends T> arg0) {
        return fail(); 
    }
    @Override public boolean addAll(int arg0, Collection<? extends T> arg1) {
        return fail();
    }

    /**
     * clear() allows setting all members of the list to null
     */
    @Override public void clear() {
        ListIterator<T> it = this.list.listIterator();

        while (it.hasNext())
        {
            it.set(null);
            it.next();
        }
    }
    @Override public boolean contains(Object o) {
        return this.list.contains(o);
    }
    @Override public boolean containsAll(Collection<?> c) {
        return this.list.containsAll(c);
    }
    @Override public T get(int index) { return this.list.get(index); }
    @Override public int indexOf(Object o) { return this.list.indexOf(o); }
    @Override public boolean isEmpty() { return false; }
    @Override public Iterator<T> iterator() { 
        return listIterator();
    }
    @Override public int lastIndexOf(Object o) { return this.list.lastIndexOf(o); }
    @Override public ListIterator<T> listIterator() {
        return IteratorWrapper.wrap(this.list.listIterator());
    }
    @Override public ListIterator<T> listIterator(int index) {
        return IteratorWrapper.wrap(this.list.listIterator(index));
    }
    @Override public boolean remove(Object o) { return fail(); }
    @Override public T remove(int index) { fail(); return fail(); }
    @Override public boolean removeAll(Collection<?> c) { return fail(); }
    @Override public boolean retainAll(Collection<?> c) { return fail(); }

    @Override public T set(int index, T element) { return this.list.set(index, element); }
    @Override public int size() { return this.list.size(); }
    @Override public List<T> subList(int fromIndex, int toIndex) {
        return new RestrictedListWrapper<T>(this.list.subList(fromIndex, toIndex));
    }
    @Override public Object[] toArray() { return this.list.toArray(); }
    @Override public <T> T[] toArray(T[] a) { return this.list.toArray(a); }
}
有一个这样的类

装饰另一个列表以固定大小 阻止添加/删除

添加、删除、清除和保留 操作不受支持。布景 方法是允许的,因为它不允许 更改列表大小


就我个人而言,我不会费心重新发明轮子。apachecommons有一个ListUtils。fixedSizeList就是这样做的,毫无疑问Google java类也有一个。

您错过了:

toString
equals
hashCode
清除中断LSP

可能应该实现java.io.Serializable

返回的实现应该实现java.util.RandomAccess,当且仅当目标也实现时。使用静态创建方法而不是裸构造函数的最高标记

应该在创建时测试目标参数是否为null,而不是等待对其调用方法


不需要到处都这样。

你真的需要包装一个任意的支持列表吗?或者你只需要一个固定大小的列表?如果是后者,JDK有:


List foos=Arrays.asListnew Foo[42]

与skauffman的答案类似,您可以使用带有可变E类型的库ImmutableList。不完全是list.seti,E,但list.geti.setstate可能足够接近

这可能看起来很琐碎,也许只是因为我现在睡眠不足,但是有什么特别的原因你不只是对列表进行子类化,并用受保护的或私有的方法覆盖add/set?@avpx,而且,正如Jason已经注意到的,你可以通过迭代器删除项。啊,好吧。我想我错过了什么。不,我们没有——以前从来没有听说过需要它。