Fixed indentation.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1377487 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Thomas Neidhart 2012-08-26 19:21:16 +00:00
parent 8338b9a252
commit 25ebc31559
1 changed files with 342 additions and 345 deletions

View File

@ -49,389 +49,386 @@ import org.apache.commons.collections.set.UnmodifiableSet;
*/ */
public class SetUniqueList<E> extends AbstractSerializableListDecorator<E> { public class SetUniqueList<E> extends AbstractSerializableListDecorator<E> {
/** Serialization version */ /** Serialization version. */
private static final long serialVersionUID = 7196982186153478694L; private static final long serialVersionUID = 7196982186153478694L;
/** /** Internal Set to maintain uniqueness. */
* Internal Set to maintain uniqueness. protected final Set<E> set;
*/
protected final Set<E> set;
/** /**
* Factory method to create a SetList using the supplied list to retain * Factory method to create a SetList using the supplied list to retain
* order. * order.
* <p> * <p>
* If the list contains duplicates, these are removed (first indexed one * If the list contains duplicates, these are removed (first indexed one
* kept). A <code>HashSet</code> is used for the set behaviour. * kept). A <code>HashSet</code> is used for the set behaviour.
* *
* @param <E> * @param <E>
* the element type * the element type
* @param list * @param list
* the list to decorate, must not be null * the list to decorate, must not be null
* @return a new {@link SetUniqueList} * @return a new {@link SetUniqueList}
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if list is null * if list is null
*/ */
public static <E> SetUniqueList<E> setUniqueList(List<E> list) { public static <E> SetUniqueList<E> setUniqueList(List<E> list) {
if (list == null) { if (list == null) {
throw new IllegalArgumentException("List must not be null"); throw new IllegalArgumentException("List must not be null");
} }
if (list.isEmpty()) { if (list.isEmpty()) {
return new SetUniqueList<E>(list, new HashSet<E>()); return new SetUniqueList<E>(list, new HashSet<E>());
} }
List<E> temp = new ArrayList<E>(list); List<E> temp = new ArrayList<E>(list);
list.clear(); list.clear();
SetUniqueList<E> sl = new SetUniqueList<E>(list, new HashSet<E>()); SetUniqueList<E> sl = new SetUniqueList<E>(list, new HashSet<E>());
sl.addAll(temp); sl.addAll(temp);
return sl; return sl;
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
/** /**
* Constructor that wraps (not copies) the List and specifies the set to * Constructor that wraps (not copies) the List and specifies the set to
* use. * use.
* <p> * <p>
* The set and list must both be correctly initialised to the same elements. * The set and list must both be correctly initialised to the same elements.
* *
* @param set * @param set
* the set to decorate, must not be null * the set to decorate, must not be null
* @param list * @param list
* the list to decorate, must not be null * the list to decorate, must not be null
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if set or list is null * if set or list is null
*/ */
protected SetUniqueList(List<E> list, Set<E> set) { protected SetUniqueList(List<E> list, Set<E> set) {
super(list); super(list);
if (set == null) { if (set == null) {
throw new IllegalArgumentException("Set must not be null"); throw new IllegalArgumentException("Set must not be null");
} }
this.set = set; this.set = set;
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
/** /**
* Gets an unmodifiable view as a Set. * Gets an unmodifiable view as a Set.
* *
* @return an unmodifiable set view * @return an unmodifiable set view
*/ */
public Set<E> asSet() { public Set<E> asSet() {
return UnmodifiableSet.unmodifiableSet(set); return UnmodifiableSet.unmodifiableSet(set);
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
/** /**
* Adds an element to the list if it is not already present. * Adds an element to the list if it is not already present.
* <p> * <p>
* <i>(Violation)</i> The <code>List</code> interface requires that this * <i>(Violation)</i> The <code>List</code> interface requires that this
* method returns <code>true</code> always. However this class may return * method returns <code>true</code> always. However this class may return
* <code>false</code> because of the <code>Set</code> behaviour. * <code>false</code> because of the <code>Set</code> behaviour.
* *
* @param object * @param object
* the object to add * the object to add
* @return true if object was added * @return true if object was added
*/ */
@Override @Override
public boolean add(E object) { public boolean add(E object) {
// gets initial size // gets initial size
final int sizeBefore = size(); final int sizeBefore = size();
// adds element if unique // adds element if unique
add(size(), object); add(size(), object);
// compares sizes to detect if collection changed // compares sizes to detect if collection changed
return (sizeBefore != size()); return (sizeBefore != size());
} }
/** /**
* Adds an element to a specific index in the list if it is not already * Adds an element to a specific index in the list if it is not already
* present. * present.
* <p> * <p>
* <i>(Violation)</i> The <code>List</code> interface makes the assumption * <i>(Violation)</i> The <code>List</code> interface makes the assumption
* that the element is always inserted. This may not happen with this * that the element is always inserted. This may not happen with this
* implementation. * implementation.
* *
* @param index * @param index
* the index to insert at * the index to insert at
* @param object * @param object
* the object to add * the object to add
*/ */
@Override @Override
public void add(int index, E object) { public void add(int index, E object) {
// adds element if it is not contained already // adds element if it is not contained already
if (set.contains(object) == false) { if (set.contains(object) == false) {
super.add(index, object); super.add(index, object);
set.add(object); set.add(object);
} }
} }
/** /**
* Adds a collection of objects to the end of the list avoiding duplicates. * Adds a collection of objects to the end of the list avoiding duplicates.
* <p> * <p>
* Only elements that are not already in this list will be added, and * Only elements that are not already in this list will be added, and
* duplicates from the specified collection will be ignored. * duplicates from the specified collection will be ignored.
* <p> * <p>
* <i>(Violation)</i> The <code>List</code> interface makes the assumption * <i>(Violation)</i> The <code>List</code> interface makes the assumption
* that the elements are always inserted. This may not happen with this * that the elements are always inserted. This may not happen with this
* implementation. * implementation.
* *
* @param coll * @param coll
* the collection to add in iterator order * the collection to add in iterator order
* @return true if this collection changed * @return true if this collection changed
*/ */
@Override @Override
public boolean addAll(Collection<? extends E> coll) { public boolean addAll(Collection<? extends E> coll) {
return addAll(size(), coll); return addAll(size(), coll);
} }
/** /**
* Adds a collection of objects a specific index in the list avoiding * Adds a collection of objects a specific index in the list avoiding
* duplicates. * duplicates.
* <p> * <p>
* Only elements that are not already in this list will be added, and * Only elements that are not already in this list will be added, and
* duplicates from the specified collection will be ignored. * duplicates from the specified collection will be ignored.
* <p> * <p>
* <i>(Violation)</i> The <code>List</code> interface makes the assumption * <i>(Violation)</i> The <code>List</code> interface makes the assumption
* that the elements are always inserted. This may not happen with this * that the elements are always inserted. This may not happen with this
* implementation. * implementation.
* *
* @param index * @param index
* the index to insert at * the index to insert at
* @param coll * @param coll
* the collection to add in iterator order * the collection to add in iterator order
* @return true if this collection changed * @return true if this collection changed
*/ */
@Override @Override
public boolean addAll(int index, Collection<? extends E> coll) { public boolean addAll(int index, Collection<? extends E> coll) {
final List<E> temp = new ArrayList<E>(); final List<E> temp = new ArrayList<E>();
for (E e : coll) { for (E e : coll) {
if (set.add(e)) { if (set.add(e)) {
temp.add(e); temp.add(e);
} }
} }
return super.addAll(index, temp); return super.addAll(index, temp);
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
/** /**
* Sets the value at the specified index avoiding duplicates. * Sets the value at the specified index avoiding duplicates.
* <p> * <p>
* The object is set into the specified index. Afterwards, any previous * The object is set into the specified index. Afterwards, any previous
* duplicate is removed If the object is not already in the list then a * duplicate is removed If the object is not already in the list then a
* normal set occurs. If it is present, then the old version is removed. * normal set occurs. If it is present, then the old version is removed.
* *
* @param index * @param index
* the index to insert at * the index to insert at
* @param object * @param object
* the object to set * the object to set
* @return the previous object * @return the previous object
*/ */
@Override @Override
public E set(int index, E object) { public E set(int index, E object) {
int pos = indexOf(object); int pos = indexOf(object);
E removed = super.set(index, object); E removed = super.set(index, object);
if (pos != -1 && pos != index) { if (pos != -1 && pos != index) {
// the object is already in the uniq list // the object is already in the uniq list
// (and it hasn't been swapped with itself) // (and it hasn't been swapped with itself)
super.remove(pos); // remove the duplicate by index super.remove(pos); // remove the duplicate by index
} }
set.add(object); // add the new item to the unique set set.add(object); // add the new item to the unique set
set.remove(removed); // remove the item deleted by the set set.remove(removed); // remove the item deleted by the set
return removed; // return the item deleted by the set return removed; // return the item deleted by the set
} }
@Override @Override
public boolean remove(Object object) { public boolean remove(Object object) {
boolean result = set.remove(object); boolean result = set.remove(object);
if (result) { if (result) {
super.remove(object); super.remove(object);
} }
return result; return result;
} }
@Override @Override
public E remove(int index) { public E remove(int index) {
E result = super.remove(index); E result = super.remove(index);
set.remove(result); set.remove(result);
return result; return result;
} }
@Override @Override
public boolean removeAll(Collection<?> coll) { public boolean removeAll(Collection<?> coll) {
boolean result = false; boolean result = false;
for (Iterator<?> it = coll.iterator(); it.hasNext();) { for (Iterator<?> it = coll.iterator(); it.hasNext();) {
result |= remove(it.next()); result |= remove(it.next());
} }
return result; return result;
} }
@Override @Override
public boolean retainAll(Collection<?> coll) { public boolean retainAll(Collection<?> coll) {
Set<Object> setRetainAll = new HashSet<Object>(); Set<Object> setRetainAll = new HashSet<Object>();
for (Iterator<?> it = coll.iterator(); it.hasNext();) { for (Iterator<?> it = coll.iterator(); it.hasNext();) {
Object next = it.next(); Object next = it.next();
if (set.contains(next)) { if (set.contains(next)) {
setRetainAll.add(next); setRetainAll.add(next);
} }
} }
if (setRetainAll.size() == set.size()) { if (setRetainAll.size() == set.size()) {
return false; return false;
} }
if (setRetainAll.size() == 0) { if (setRetainAll.size() == 0) {
clear(); clear();
} else { } else {
for (Iterator<E> it = iterator(); it.hasNext();) { for (Iterator<E> it = iterator(); it.hasNext();) {
if (!setRetainAll.contains(it.next())) { if (!setRetainAll.contains(it.next())) {
it.remove(); it.remove();
} }
} }
} }
return true; return true;
} }
@Override @Override
public void clear() { public void clear() {
super.clear(); super.clear();
set.clear(); set.clear();
} }
@Override @Override
public boolean contains(Object object) { public boolean contains(Object object) {
return set.contains(object); return set.contains(object);
} }
@Override @Override
public boolean containsAll(Collection<?> coll) { public boolean containsAll(Collection<?> coll) {
return set.containsAll(coll); return set.containsAll(coll);
} }
@Override @Override
public Iterator<E> iterator() { public Iterator<E> iterator() {
return new SetListIterator<E>(super.iterator(), set); return new SetListIterator<E>(super.iterator(), set);
} }
@Override @Override
public ListIterator<E> listIterator() { public ListIterator<E> listIterator() {
return new SetListListIterator<E>(super.listIterator(), set); return new SetListListIterator<E>(super.listIterator(), set);
} }
@Override @Override
public ListIterator<E> listIterator(int index) { public ListIterator<E> listIterator(int index) {
return new SetListListIterator<E>(super.listIterator(index), set); return new SetListListIterator<E>(super.listIterator(index), set);
} }
@Override @Override
public List<E> subList(int fromIndex, int toIndex) { public List<E> subList(int fromIndex, int toIndex) {
List<E> superSubList = super.subList(fromIndex, toIndex); List<E> superSubList = super.subList(fromIndex, toIndex);
Set<E> subSet = createSetBasedOnList(set, superSubList); Set<E> subSet = createSetBasedOnList(set, superSubList);
return new SetUniqueList<E>(superSubList, subSet); return new SetUniqueList<E>(superSubList, subSet);
} }
/** /**
* Create a new {@link Set} with the same type as the provided {@code set} * Create a new {@link Set} with the same type as the provided {@code set}
* and populate it with all elements of {@code list}. * and populate it with all elements of {@code list}.
* *
* @param set * @param set
* the {@link Set} to be used as return type, must not be null * the {@link Set} to be used as return type, must not be null
* @param list * @param list
* the {@link List} to populate the {@link Set} * the {@link List} to populate the {@link Set}
* @return a new {@link Set} populated with all elements of the provided * @return a new {@link Set} populated with all elements of the provided
* {@link List} * {@link List}
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected Set<E> createSetBasedOnList(Set<E> set, List<E> list) { protected Set<E> createSetBasedOnList(Set<E> set, List<E> list) {
Set<E> subSet; Set<E> subSet;
if (set.getClass().equals(HashSet.class)) { if (set.getClass().equals(HashSet.class)) {
subSet = new HashSet<E>(list.size()); subSet = new HashSet<E>(list.size());
} else { } else {
try { try {
subSet = set.getClass().newInstance(); subSet = set.getClass().newInstance();
} catch (InstantiationException ie) { } catch (InstantiationException ie) {
subSet = new HashSet<E>(); subSet = new HashSet<E>();
} catch (IllegalAccessException iae) { } catch (IllegalAccessException iae) {
subSet = new HashSet<E>(); subSet = new HashSet<E>();
} }
} }
subSet.addAll(list); subSet.addAll(list);
return subSet; return subSet;
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
/** /**
* Inner class iterator. * Inner class iterator.
*/ */
static class SetListIterator<E> extends AbstractIteratorDecorator<E> { static class SetListIterator<E> extends AbstractIteratorDecorator<E> {
protected final Set<E> set; protected final Set<E> set;
protected E last = null; protected E last = null;
protected SetListIterator(Iterator<E> it, Set<E> set) { protected SetListIterator(Iterator<E> it, Set<E> set) {
super(it); super(it);
this.set = set; this.set = set;
} }
@Override @Override
public E next() { public E next() {
last = super.next(); last = super.next();
return last; return last;
} }
@Override @Override
public void remove() { public void remove() {
super.remove(); super.remove();
set.remove(last); set.remove(last);
last = null; last = null;
} }
} }
/** /**
* Inner class iterator. * Inner class iterator.
*/ */
static class SetListListIterator<E> extends static class SetListListIterator<E> extends
AbstractListIteratorDecorator<E> { AbstractListIteratorDecorator<E> {
protected final Set<E> set; protected final Set<E> set;
protected E last = null; protected E last = null;
protected SetListListIterator(ListIterator<E> it, Set<E> set) { protected SetListListIterator(ListIterator<E> it, Set<E> set) {
super(it); super(it);
this.set = set; this.set = set;
} }
@Override @Override
public E next() { public E next() {
last = super.next(); last = super.next();
return last; return last;
} }
@Override @Override
public E previous() { public E previous() {
last = super.previous(); last = super.previous();
return last; return last;
} }
@Override @Override
public void remove() { public void remove() {
super.remove(); super.remove();
set.remove(last); set.remove(last);
last = null; last = null;
} }
@Override @Override
public void add(E object) { public void add(E object) {
if (set.contains(object) == false) { if (set.contains(object) == false) {
super.add(object); super.add(object);
set.add(object); set.add(object);
} }
} }
@Override @Override
public void set(E object) { public void set(E object) {
throw new UnsupportedOperationException( throw new UnsupportedOperationException("ListIterator does not support set");
"ListIterator does not support set"); }
} }
}
} }