/* * Copyright (c) 2016 Fraunhofer IGD * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Fraunhofer IGD <http://www.igd.fraunhofer.de/> */ package de.fhg.igd.geom.algorithm.sweepline; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; /** * A list that is always sorted. * * @author Michel Kraemer * @param <E> the type of the list elements */ public class SortedCollection<E> implements Collection<E> { /** * The actual list */ private List<E> _list = new ArrayList<E>(); /** * The comparator used to sort the items in the collection */ private Comparator<? super E> _comp; /** * Default constructor */ public SortedCollection() { // nothing to do here } /** * Copy constructor * * @param c the collection to copy */ public SortedCollection(Collection<? extends E> c) { addAll(c); } /** * Default constructor * * @param comp the comparator used to sort the elements in this list */ public SortedCollection(Comparator<? super E> comp) { _comp = comp; } /** * Copy constructor * * @param c the collection to copy * @param comp the comparator used to sort the elements in this list */ public SortedCollection(Collection<? extends E> c, Comparator<? super E> comp) { this(comp); addAll(c); } /** * @see Collection#add(Object) */ @Override public boolean add(E e) { int index = Collections.binarySearch(_list, e, _comp); if (index < 0) { index = -(index + 1); } _list.add(index, e); return true; } /** * @see Collection#addAll(Collection) */ @Override public boolean addAll(Collection<? extends E> c) { for (E e : c) { if (!add(e)) { throw new IllegalStateException(); } } return !c.isEmpty(); } /** * @see Collection#contains(Object) */ @SuppressWarnings("unchecked") @Override public boolean contains(Object o) { int index = Collections.binarySearch(_list, (E) o, _comp); return (index >= 0); } /** * @see Collection#containsAll(Collection) */ @Override public boolean containsAll(Collection<?> c) { for (Object o : c) { if (!contains(o)) { return false; } } return true; } /** * Gets the element at the given position * * @param index the position * @return the element * @throws IndexOutOfBoundsException if index is out of bounds */ public E get(int index) { return _list.get(index); } /** * Searches for the index of a given element * * @param e the element * @return the index or -1 if the list does not contain this element */ public int indexOf(E e) { int index = Collections.binarySearch(_list, e, _comp); if (index < 0) { return -1; } return index; } /** * @see Collection#iterator() */ @Override public Iterator<E> iterator() { return Collections.unmodifiableList(_list).iterator(); } /** * @see Collection#remove(Object) */ @SuppressWarnings("unchecked") @Override public boolean remove(Object o) { int index = Collections.binarySearch(_list, (E) o, _comp); if (index < 0) { return false; } _list.remove(index); return true; } /** * Removes the element at the given position from the list * * @param index the position * @return the removed element * @throws IndexOutOfBoundsException if index is out of bounds */ public E remove(int index) { return _list.remove(index); } /** * @see Collection#removeAll(Collection) */ @Override public boolean removeAll(Collection<?> c) { boolean result = false; for (Object o : c) { result |= remove(o); } return result; } /** * @see Collection#retainAll(Collection) */ @Override public boolean retainAll(Collection<?> c) { return _list.retainAll(c); } /** * @see Collection#size() */ @Override public int size() { return _list.size(); } /** * @see Collection#isEmpty() */ @Override public boolean isEmpty() { return _list.isEmpty(); } /** * @see Collection#clear() */ @Override public void clear() { _list.clear(); } /** * @see Collection#toArray() */ @Override public Object[] toArray() { return _list.toArray(); } /** * @see Collection#toArray(Object[]) */ @Override public <T> T[] toArray(T[] a) { return _list.toArray(a); } /** * Resorts this list (for example, if the comparator changed its internal * state) */ public void resort() { Collections.sort(_list, _comp); } }