2017-02-24 9 views
2

要素の追加のみを許可するが、要素の削除を許可しないJava java.util.Listを作成する可能性があるかどうかを知りたいですか?Javaリストのみ追加削除なし

1つの方法で、削除メソッドをオーバーライドすることを考えています。提案してください。

+3

なぜ削除使用してから、プログラマを停止するすべての努力に行きますか?または、Listインターフェイスを継承するカスタムオブジェクトを実装している場合は、単に何もしない関数としてremoveをオーバーライドします。削除を停止するために別のListオブジェクトを作成する際の手間は不要ですか? –

+3

最も簡単なアプローチは、既存のリスト実装のサブクラス1になり、removeメソッドをオーバーライドすることです。 –

+1

リストクラスを上書きすることに同意しましたが、何もしない代わりに例外を発生させることをお勧めしますので、ユーザーは何か間違っていると知っています –

答えて

3

このデコレータパターンを使用して達成することができます。この方法は、それは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ありがとうございました。私は元の 'subList()'を 'UnremovableList'でラップしました - 今はうまくいくはずです – 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

関連する問題