/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany This library is free software; you can redistribute it and/or modify it 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. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; If not, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.core.collections.bags; import java.util.Iterator; import java.util.List; import xxl.core.cursors.Cursor; import xxl.core.functions.AbstractFunction; import xxl.core.functions.Function; import xxl.core.predicates.Predicate; /** * The interface bag represents a data type that is able to contain any kind of * object and performs no duplicate detection. More formally, this interface * models a kind of mathematical <i>multiset</i> abstraction. * * <p>The bag only provides methods for insertion of objetcs and removal of all * elements, but for accessing or removing <i>single</i> elements, a cursor * iterating over all elements of the bag must be created by calling * <code>cursor()</code>. The sequence of elements delivered by this cursor has * no predefined order. However, a subclass may define such an order.</p> * * @param <E> the type of the elements this bag is able to store. * @see Cursor * @see Function * @see Iterator */ public interface Bag<E> { /** * A factory method to create a default bag. Each concrete implementation * of bag except for ListBag should have a function FACTORY_METHOD that * implements three variants of <code>invoke</code> * <ul> * <dl> * <dt><li><code>Bag invoke()</code>:</dt> * <dd>returns <code>new Bag()</code>.</dd> * <dt><li><code>Bag invoke(Object iterator)</code>:</dt> * <dd>returns <code>new Bag(iterator)</code>.</dd> * <dt><li><code>Bag invoke(List<? extends Object> internalDataStructure)</code>:</dt> * <dd>returns <code>new Bag((<<i>InternalDataStructure></i>)internalDataStructure.get(0))</code>.</dd> * </dl> * </ul> * This factory method creates a new ListBag. It may be invoked with a * <i>parameter list</i> (for further details see {@link Function}) of * lists, an iterator or without any parameters. A <i>parameter list</i> of * lists will be used to initialize the internally used list with the list * at index 0 and an iterator will be used to insert the contained elements * into the new ListBag. * * @see Function */ public static final Function<Object,ListBag<Object>> FACTORY_METHOD = new AbstractFunction<Object,ListBag<Object>> () { @Override public ListBag<Object> invoke() { return new ListBag<Object>(); } @Override public ListBag<Object> invoke(Object iterator) { return new ListBag<Object>((Iterator<?>)iterator); } @Override public ListBag<Object> invoke(List<? extends Object> list) { return new ListBag<Object>((List<Object>)list.get(0)); } }; /** * Removes all of the elements from this bag. The bag will be empty after * this call so that <code>size() == 0</code>. */ public abstract void clear(); /** * Closes this bag and releases any system resources associated with it. * This operation is idempotent, i.e., multiple calls of this method take * the same effect as a single call. When needed, a closed bag can be * implicit reopened by a consecutive call to one of its methods. Because * of having an unspecified behavior when this bag is closed every cursor * iterating over the elements of this bag must be closed. * * <p><b>Note:</b> This method is very important for bags using external * resources like files or JDBC resources.</p> */ public abstract void close(); /** * Returns a cursor to iterate over the elements in this bag without any * predefined sequence. The cursor is specifying a <i>view</i> on the * elements of this bag so that closing the cursor takes no effect on the * bag (e.g., not closing the bag). The behavior of the cursor is * unspecified if this bag is modified while the cursor is in progress in * any way other than by calling the methods of the cursor. So, when the * implementation of this cursor cannot guarantee that the cursor is in a * valid state after modifying the underlying bag every method of the cursor * except <code>close()</code> should throw a * <code>ConcurrentModificationException</code>. * * @return a cursor to iterate over the elements in this bag without any * predefined sequence. */ public abstract Cursor<E> cursor(); /** * Adds the specified element to this bag. This method does not perform any * kind of <i>duplicate detection</i>. * * @param object element to be added to this bag. */ public abstract void insert(E object); /** * Adds all of the elements in the specified iterator to this bag. This * method does not perform any kind of <i>duplicate detection.</i> The * behavior of this operation is unspecified if the specified iterator is * modified while the operation is in progress. * * @param objects iterator whose elements are to be added to this bag. */ public abstract void insertAll(Iterator<? extends E> objects); /** * Returns the number of elements in this bag (its cardinality). If this * bag contains more than <code>Integer.MAX_VALUE</code> elements, * <code>Integer.MAX_VALUE</code> is returned. * * @return the number of elements in this bag (its cardinality). */ public abstract int size(); /** * Returns a cursor to iterate over all elements in this bag for which the * given predicate returns <code>true</code>. This method is very similar * to the cursor method except that its result is determined by a * predicate. A possible implementation filters the result of the cursor * method using the following code * <code><pre> * return new Filter<E>(cursor(), predicate); * </pre></code> * Note, that this method is implemented in <i>AbstractBag</i>. * * <p>The default implementation of this method is not very interesting, * but the method is very import for some bags. When the data structure * that is internally used for storing the elements of this bag is able to * handle with queries, this method can be implemented very efficient by * passing the query to the data structure. For example a range query on a * bag that internally uses a R-tree to store its elements will be more * efficient when it is proceed on the R-tree itself.</p> * * <p>Like the cursor returned by the cursor method, this cursor's behavior * is unspecified if this bag is modified while the cursor is in progress * in any way other than by calling the methods of the cursor.</p> * * @param predicate a predicate that determines whether an element of this * bag should be returned or not. * @return a cursor to iterate over all elements in this bag for which the * given predicate returns <code>true</code>. */ public abstract Cursor<E> query(Predicate<? super E> predicate); }