2017-02-24 80 views
2

我想知道是否有可能创建一个Java java.util.List,它只允许添加元素但不允许删除元素?Java list only only addition删除

我正在考虑重写删除方法的一种方法。请建议。

+3

为什么要停止使用删除一个程序员的所有的努力?或者,如果您正在实现继承List接口的自定义对象,则只需将remove重写为一个不做任何事情的函数。在创建一个不同的List对象停止删除的麻烦似乎没有必要? –

+3

最简单的方法是对现有的List实现中的一个子类进行子类化并覆盖remove方法。 –

+1

同意覆盖列表类,但没有做任何事我会建议引发异常,所以用户知道他们做错了什么 –

回答

3

这可以使用Decorator模式来实现。这样,它可以适用于实现List所有容器:

private static class UnremovableList<E> implements List<E> { 
    private List<E> innerContainer; 

    public UnremovableList(List<E> original) { 
     innerContainer = original 
    } 

    @Override 
    public void add(int location, E object) { 
     innerContainer.add(location, object); 
    } 

    @Override 
    public boolean add(E object) { 
     return innerContainer.add(object); 
    } 

    @Override 
    public boolean addAll(int location, Collection<? extends E> collection) { 
     return innerContainer.addAll(location, collection); 
    } 

    @Override 
    public boolean addAll(Collection<? extends E> collection) { 
     return innerContainer.addAll(collection); 
    } - 

    @Override 
    public void clear() { 
     throw new UnsupportedOperationException(); 
    } 

    @Override 
    public boolean contains(Object object) { 
     return innerContainer.contains(object); 
    } 

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

    @Override 
    public E get(int location) { 
     return innerContainer.get(location); 
    } 

    @Override 
    public int indexOf(Object object) { 
     return innerContainer.indexOf(object); 
    } 

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

    @NonNull 
    @Override 
    public ListIterator<E> listIterator() { 
     return listIterator(0); 
    } 

    @NonNull 
    @Override 
    public Iterator<E> iterator() { 
     return new Iterator<E>() { 
      Iterator<E> iterator = innerContainer.iterator(); 

      @Override public boolean hasNext() { 
       return iterator.hasNext(); 
      } 

      @Override public E next() { 
       return iterator.next(); 
      } 

      @Override public void remove() { 
       throw new UnsupportedOperationException(); 
      } 
     }; 
    } 

    @Override 
    public ListIterator<E> listIterator(final int location) { 
     return new ListIterator<E>() { 
      ListIterator<E> iterator = innerContainer.listIterator(location); 

      @Override public void add(E object) { 
       throw new UnsupportedOperationException(); 
      } 

      @Override public boolean hasNext() { 
       return iterator.hasNext(); 
      } 

      @Override public boolean hasPrevious() { 
       return iterator.hasPrevious(); 
      } 

      @Override public E next() { 
       return iterator.next(); 
      } 

      @Override public int nextIndex() { 
       return iterator.nextIndex(); 
      } 

      @Override public E previous() { 
       return iterator.previous(); 
      } 

      @Override public int previousIndex() { 
       return iterator.previousIndex(); 
      } 

      @Override public void remove() { 
       throw new UnsupportedOperationException(); 
      } 

      @Override public void set(E object) { 
       throw new UnsupportedOperationException(); 
      } 
     }; 
    } 

    @Override 
    public int lastIndexOf(Object object) { 
     return innerContainer.lastIndexOf(object); 
    } 

    @Override 
    public E remove(int location) { 
     throw new UnsupportedOperationException(); 
    } 

    @Override 
    public boolean remove(Object object) { 
     throw new UnsupportedOperationException(); 
    } 

    @Override 
    public boolean removeAll(Collection<?> collection) { 
     throw new UnsupportedOperationException(); 
    } 

    @Override 
    public boolean retainAll(Collection<?> collection) { 
     throw new UnsupportedOperationException(); 
    } 

    @Override 
    public E set(int location, E object) { 
     return innerContainer.set(location, object); 
    } 

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

    @NonNull 
    @Override 
    public List<E> subList(int start, int end) { 
     return new UnremovableList(innerContainer.subList(start, end)); 
    } 

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

    @NonNull 
    @Override 
    public <T> T[] toArray(T[] array) { 
     return innerContainer.toArray(array); 
    } 
} 

用法:

List<String> stableList = new UnremovableList(Arrays.asList("A", "B", "C")); 
+0

有利于构图而不是继承,以及支持迭代器的奖励点。但是'subList()'可能需要类似的处理。 –

+0

@JiriTousek谢谢。我用'UnremovableList'封装了原始'subList()' - 现在它应该可以工作 – j2ko

4

可以扩展现有列表实现类并覆盖所有公共删除方法,但是它有相当多的方法来重写(甚至更多,下面都是我很快就找到)

public class UnDeletableList<E> extends ArrayList<E> { 
    @Override 
    public E remove(int index) { 
     throw new UnsupportedOperationException("don't remove from this list"); 
    } 

    @Override 
    public boolean remove(Object o) { 
     throw new UnsupportedOperationException("don't remove from this list"); 
    } 

    @Override 
    public boolean removeAll(Collection<?> o) { 
     throw new UnsupportedOperationException("don't remove from this list"); 
    } 

    @Override 
    public boolean retainAll(Collection<?> o) { 
     throw new UnsupportedOperationException("don't remove from this list"); 
    } 

    @Override 
    public void clear() { 
     throw new UnsupportedOperationException("don't remove from this list"); 
    } 

    // OPTIONAL IN CASE OF EXTRA STRICTNESS 
    @Override 
    public void replaceAll(UnaryOperator<E> u) { 
     throw new UnsupportedOperationException("don't remove from this list"); 
    } 

    @Override 
    public E set(int i, E e) { 
     throw new UnsupportedOperationException("don't remove from this list"); 
    } 
} 
+1

我会抛出'UnsupportedOperationException'而不是默默无闻,这会导致其他开发者的不满当他们尝试调试后发现你的代码为什么他们的移除调用似乎不起作用。 – Bohemian

+0

取决于OP的“去除”元素的定义,但你可能也想禁止'set(int,E)'和'replaceAll(UnaryOperator )'(自Java 8以来) –

+0

将此添加到答案@Bohemian – baao