変更の可/不可を切り替えられるコレクション
public class ConditionalModifiableCollection<T> implements Collection<T> { private class ConditionalModifiableIterator implements Iterator<T> { private Iterator<T> it = baseCollection.iterator(); @Override public boolean hasNext() { return it.hasNext(); } @Override public T next() { return it.next(); } @Override public void remove() { if (!isModifiable()) { throw new IllegalStateException(); } it.remove(); } } private Collection<T> baseCollection; private boolean modifiable = true; public ConditionalModifiableCollection(Collection<T> collection) { baseCollection = collection; } public boolean isModifiable() { return modifiable; } public void setModifiable(boolean value) { modifiable = value; } @Override public int size() { return baseCollection.size(); } @Override public boolean isEmpty() { return baseCollection.isEmpty(); } @Override public boolean contains(Object o) { return baseCollection.contains(o); } @Override public Object[] toArray() { return baseCollection.toArray(); } @Override public <T> T[] toArray(T[] a) { return baseCollection.toArray(a); } @Override public boolean containsAll(Collection<?> c) { return baseCollection.containsAll(c); } @Override public Iterator<T> iterator() { return new ConditionalModifiableIterator(); } @Override public boolean add(T e) { if (!isModifiable()) { throw new IllegalStateException(); } return baseCollection.add(e); } @Override public boolean remove(Object o) { if (!isModifiable()) { throw new IllegalStateException(); } return baseCollection.remove(o); } @Override public boolean addAll(Collection<? extends T> c) { if (!isModifiable()) { throw new IllegalStateException(); } return baseCollection.addAll(c); } @Override public boolean removeAll(Collection<?> c) { if (!isModifiable()) { throw new IllegalStateException(); } return baseCollection.removeAll(c); } @Override public boolean retainAll(Collection<?> c) { if (!isModifiable()) { throw new IllegalStateException(); } return baseCollection.retainAll(c); } @Override public void clear() { if (!isModifiable()) { throw new IllegalStateException(); } baseCollection.clear(); } }
public class ConditionalModifiableMap<K, V> implements Map<K, V> { private class InnerCollection<T> extends ConditionalModifiableCollection<T> { public InnerCollection(Collection<T> set) { super(set); } @Override public boolean isModifiable() { return ConditionalModifiableMap.this.isModifiable(); } @Override public void setModifiable(boolean value) { throw new UnsupportedOperationException(); } } private class InnerSet<T> extends InnerCollection<T> implements Set<T> { public InnerSet(Set<T> set) { super(set); } } private class InnerEntrySet extends InnerSet<Map.Entry<K, V>> { private class InnerEntry implements Map.Entry<K, V> { private Map.Entry<K, V> entry; private InnerEntry(Map.Entry<K, V> entry) { this.entry = entry; } @Override public K getKey() { return entry.getKey(); } @Override public V getValue() { return entry.getValue(); } @Override public V setValue(V value) { if (!isModifiable()) { throw new IllegalStateException(); } return entry.setValue(value); } } private class InnerEntrySetIterator implements Iterator<Map.Entry<K, V>> { private Iterator<Map.Entry<K, V>> iterator; private InnerEntrySetIterator(Iterator<Map.Entry<K, V>> iterator) { this.iterator = iterator; } @Override public boolean hasNext() { return iterator.hasNext(); } @Override public Map.Entry<K, V> next() { return new InnerEntry(iterator.next()); } @Override public void remove() { // iteratorはConditionalModifiableIteratorでしかあり得ないが省略するとわかりにくいのでチェックする if (!isModifiable()) { throw new IllegalStateException(); } iterator.remove(); } } private InnerEntrySet(Set<Entry<K, V>> set) { super(set); } @Override public Iterator<Map.Entry<K, V>> iterator() { return new InnerEntrySetIterator(super.iterator()); } } private Map<K, V> baseMap; private boolean modifiable = true; public ConditionalModifiableMap(Map<K, V> map) { baseMap = map; } public boolean isModifiable() { return modifiable; } public void setModifiable(boolean value) { modifiable = value; } @Override public int size() { return baseMap.size(); } @Override public boolean isEmpty() { return baseMap.isEmpty(); } @Override public boolean containsKey(Object key) { return baseMap.containsKey(key); } @Override public boolean containsValue(Object value) { return baseMap.containsValue(value); } @Override public V get(Object key) { return baseMap.get(key); } @Override public V put(K key, V value) { if (!isModifiable()) { throw new IllegalStateException(); } return baseMap.put(key, value); } @Override public V remove(Object key) { if (!isModifiable()) { throw new IllegalStateException(); } return baseMap.remove(key); } @Override public void putAll(Map<? extends K, ? extends V> m) { if (!isModifiable()) { throw new IllegalStateException(); } baseMap.putAll(m); } @Override public void clear() { if (!isModifiable()) { throw new IllegalStateException(); } baseMap.clear(); } @Override public Set<K> keySet() { return new InnerSet<>(baseMap.keySet()); } @Override public Collection<V> values() { return new InnerCollection<>(baseMap.values()); } @Override public Set<Map.Entry<K, V>> entrySet() { return new InnerEntrySet(baseMap.entrySet()); } }
Listもいる?