/** * */ package vroom.common.utilities; import java.util.AbstractSet; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; import vroom.common.utilities.dataModel.IObjectWithID; /** * The class <code>ObjectWithIDSet</code> is an implementation of {@link Set} used to store instances of * {@link IObjectWithID}. * <p> * Creation date: Mar 29, 2012 - 3:58:55 PM * * @author Victor Pillac, <a href="http://uniandes.edu.co">Universidad de Los Andes</a>-<a * href="http://copa.uniandes.edu.co">Copa</a> <a href="http://www.emn.fr">Ecole des Mines de Nantes</a>-<a * href="http://www.irccyn.ec-nantes.fr/irccyn/d/en/equipes/Slp">SLP</a> * @version 1.0 */ public class ObjectWithIdSet<E extends IObjectWithID> extends AbstractSet<E> { private final Object[] mMask; private int mSize; private int mMinIdx; /** * Creates a new <code>ObjectWithIDSet</code> with an initial set of values. * <p> * Note that the set will not be able to handle values that are higher than the maximum id stored in {@code values} * </p> * * @param values * an initial set of values */ public ObjectWithIdSet(Collection<E> values) { int maxValue = -1; for (IObjectWithID i : values) if (i.getID() > maxValue) maxValue = i.getID(); mMask = new Object[maxValue + 1]; mMinIdx = mMask.length - 1; addAll(values); } /** * Creates a new <code>ObjectWithIDSet</code> with an initial set of values * * @param values * an initial set of values * @param maxID * the maximum id that will ever be contained in this set */ public ObjectWithIdSet(Collection<E> values, int maxID) { this(maxID); addAll(values); } /** * Creates a new empty <code>ObjectWithIDSet</code> * * @param maxID * the maximum id that will ever be contained in this set */ public ObjectWithIdSet(int maxID) { mMask = new Object[maxID + 1]; mMinIdx = mMask.length - 1; mSize = 0; } @Override public boolean contains(Object o) { if (o instanceof IObjectWithID) { int e = ((IObjectWithID) o).getID(); if (e < 0 || e >= mMask.length) return false; return mMask[e] != null; } else { return false; } } @Override public boolean add(IObjectWithID o) { Object prev = mMask[o.getID()]; if (prev == null) { mMask[o.getID()] = o; if (o.getID() < mMinIdx) mMinIdx = o.getID(); mSize++; return true; } else return false; } @Override public boolean remove(Object o) { if (o instanceof IObjectWithID) { IObjectWithID e = (IObjectWithID) o; if (e.getID() < 0 || e.getID() >= mMask.length) return false; Object prev = mMask[e.getID()]; if (prev != null) { mMask[e.getID()] = null; if (e.getID() == mMinIdx) mMinIdx++; mSize--; return true; } else return false; } else { return false; } } @Override public boolean removeAll(Collection<?> c) { boolean changed = false; for (Object o : c) changed |= remove(o); return changed; } /* * (non-Javadoc) * @see java.util.AbstractCollection#iterator() */ @Override public ObjectWithIDSetIterator iterator() { return new ObjectWithIDSetIterator(); } /* * (non-Javadoc) * @see java.util.AbstractCollection#size() */ @Override public int size() { return mSize; } /** * Return the maximum value that can be stored in this set * * @return the maximum value that can be stored in this set */ public int maxValue() { return mMask.length - 1; } @Override public void clear() { Arrays.fill(mMask, null); mSize = 0; } /** * <code>IntegerSetIterator</code> is an implementation of {@link Iterator} that iterates over an instance of * {@link IntegerSet}. This implementation iterates over the whole set in {@link IntegerSet#maxValue() maxId} steps. * <p> * Creation date: Oct 14, 2011 - 2:15:50 PM * * @author Victor Pillac, <a href="http://uniandes.edu.co">Universidad de Los Andes</a>-<a * href="http://copa.uniandes.edu.co">Copa</a> <a href="http://www.emn.fr">Ecole des Mines de Nantes</a>-<a * href="http://www.irccyn.ec-nantes.fr/irccyn/d/en/equipes/Slp">SLP</a> * @version 1.0 */ public class ObjectWithIDSetIterator implements Iterator<E> { private int mCurrent; private int mNext; /** * Creates a new <code>IntegerSetIterator</code> */ public ObjectWithIDSetIterator() { super(); mNext = mMinIdx - 1; moveToNextElement(); mMinIdx = mNext; } private void moveToNextElement() { mNext++; while (mNext < ObjectWithIdSet.this.mMask.length && ObjectWithIdSet.this.mMask[mNext] == null) mNext++; } @Override public boolean hasNext() { return mNext < ObjectWithIdSet.this.mMask.length; } @SuppressWarnings("unchecked") @Override public E next() { if (!hasNext()) throw new NoSuchElementException(); mCurrent = mNext; moveToNextElement(); return (E) ObjectWithIdSet.this.mMask[mCurrent]; } @Override public void remove() { if (mCurrent < 0) throw new IllegalStateException(); ObjectWithIdSet.this.remove(mCurrent); mCurrent = -1; } } }