2017-02-24 63 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