package edu.ualberta.med.biobank.common.action.util; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; /** * A {@link Set} that remembers the original working set, so after this * {@link Set} is modified, the added and removed elements can be determined. * This is useful if the original set is actually a subset. Then it is easier to * track the changes an individual makes to a subset of elements in collection. * <p> * This class is intended to be used with relatively small sets. * <p> * Note that it probably wouldn't save much room to track the additions and * removals separately (vs simply tracking the originals) as the most possible * room saved would be around double the size of the original set. Twice the * references is not a big deal. * * @author Jonathan Ferland * * @param <T> element type */ public class WorkingSet<T> implements Set<T> { private final Set<T> original; private final Set<T> delegate = new HashSet<T>(); // public static <E> WorkingSet<E> of(Set<E> original) { // return new WorkingSet<E>(original); // } public WorkingSet(Set<T> original) { this.original = Collections.unmodifiableSet(original); this.delegate.addAll(original); } // public void setValues(Set<T> s) { // delegate.clear(); // delegate.addAll(s); // } public Set<T> getAdditions() { Set<T> additions = new HashSet<T>(delegate); additions.removeAll(original); return additions; } public Set<T> getRemovals() { Set<T> removals = new HashSet<T>(original); removals.removeAll(delegate); return removals; } public DiffSet<T> getDiff() { return DiffSet.of(original, delegate); } public Set<T> getOriginal() { return original; } /** * Reset to the original {@link Set}. */ public void reset() { delegate.clear(); delegate.addAll(original); } @Override public boolean add(T e) { return delegate.add(e); } @Override public boolean addAll(Collection<? extends T> c) { return delegate.addAll(c); } @Override public void clear() { delegate.clear(); } @Override public boolean contains(Object o) { return delegate.contains(o); } @Override public boolean containsAll(Collection<?> c) { return delegate.containsAll(c); } @Override public boolean isEmpty() { return delegate.isEmpty(); } @Override public Iterator<T> iterator() { return delegate.iterator(); } @Override public boolean remove(Object o) { return delegate.remove(o); } @Override public boolean removeAll(Collection<?> c) { return delegate.removeAll(c); } @Override public boolean retainAll(Collection<?> c) { return delegate.retainAll(c); } @Override public int size() { return delegate.size(); } @Override public Object[] toArray() { return delegate.toArray(); } @Override public <E> E[] toArray(E[] a) { return delegate.toArray(a); } }