Copyright (c) 2008, 2016 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation
/******************************************************************************* * Copyright (c) 2008, 2016 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/
package org.eclipse.osgi.internal.serviceregistry; import java.util.*;
A Shrinkable Collection. This class provides a wrapper for a list of collections that allows items to be removed from the wrapped collections (shrinking) but does not allow items to be added to the wrapped collections.

The collections must act as sets in that each collection in the list must not have two entries which are equal.

All the optional Collection operations except add and addAll are supported. Attempting to add to the collection will result in an UnsupportedOperationException.

/** * A Shrinkable Collection. This class provides a wrapper for a list of collections * that allows items to be removed from the wrapped collections (shrinking) but * does not allow items to be added to the wrapped collections. * * <p> * The collections must act as sets in that each collection in the list * must not have two entries which are equal. * * <p> * All the optional <code>Collection</code> operations except * <code>add</code> and <code>addAll</code> are supported. Attempting to add to the * collection will result in an <code>UnsupportedOperationException</code>. * */
public class ShrinkableCollection<E> implements Collection<E> { private final Collection<? extends E> collection; private final List<Collection<? extends E>> list; public ShrinkableCollection(Collection<? extends E> c) { if (c == null) { throw new NullPointerException(); } List<Collection<? extends E>> empty = Collections.<Collection<? extends E>> emptyList(); list = empty; collection = c; } public ShrinkableCollection(Collection<? extends E> c1, Collection<? extends E> c2) { list = new ArrayList<>(2); list.add(c1); list.add(c2); collection = initComposite(list); } public ShrinkableCollection(List<Collection<? extends E>> l) { list = new ArrayList<>(l); collection = initComposite(list); } private static <E> Collection<? extends E> initComposite(List<Collection<? extends E>> collections) { int size = 0; for (Collection<? extends E> c : collections) { assert verifyNoDuplicates(c); size += c.size(); } Collection<E> result = new ArrayList<>(size); for (Collection<? extends E> c : collections) { for (E e : c) { if (!result.contains(e)) { result.add(e); } } } return result; } private static <E> boolean verifyNoDuplicates(Collection<? extends E> c) { for (E e : c) { int count = 0; for (E f : c) { if (e == null) { if (f == null) { count++; } } else { if (e.equals(f)) { count++; } } } if (count != 1) { return false; } } return true; } @Override public boolean add(E e) { throw new UnsupportedOperationException(); } @Override public boolean addAll(Collection<? extends E> c) { throw new UnsupportedOperationException(); } @Override public void clear() { collection.clear(); for (Collection<? extends E> c : list) { c.clear(); } } @Override public boolean contains(Object o) { return collection.contains(o); } @Override public boolean containsAll(Collection<?> c) { return collection.containsAll(c); } @Override public boolean isEmpty() { return collection.isEmpty(); } @Override public Iterator<E> iterator() { @SuppressWarnings("unchecked") final Iterator<E> iter = (Iterator<E>) collection.iterator(); final List<Collection<? extends E>> collections = list; if (collections.isEmpty()) { return iter; } return new Iterator<E>() { private E last; @Override public boolean hasNext() { return iter.hasNext(); } @Override public E next() { last = iter.next(); return last; } @Override public void remove() { iter.remove(); for (Collection<? extends E> c : collections) { c.remove(last); } } }; } @Override public boolean remove(Object o) { final boolean result = collection.remove(o); if (result) { for (Collection<? extends E> c : list) { c.remove(o); } } return result; } @Override public boolean removeAll(Collection<?> c) { final boolean result = collection.removeAll(c); if (result) { for (Collection<? extends E> cc : list) { cc.removeAll(c); } } return result; } @Override public boolean retainAll(Collection<?> c) { final boolean result = collection.retainAll(c); if (result) { for (Collection<? extends E> cc : list) { cc.retainAll(c); } } return result; } @Override public int size() { return collection.size(); } @Override public Object[] toArray() { return collection.toArray(); } @Override public <T> T[] toArray(T[] var0) { return collection.toArray(var0); } @Override public String toString() { return collection.toString(); } }