/* 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.queues;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import xxl.core.functions.AbstractFunction;
import xxl.core.functions.Function;
/**
* This class provides an implementation of the Queue interface with a
* LIFO (<i>last in, first out</i>) strategy that internally uses a stack
* to store its elements. It implements the <tt>peek</tt> method.<p>
*
* Usage example (1).
* <pre>
* // create a new stack queue
*
* StackQueue<Integer> queue = new StackQueue<Integer>();
*
* // open the queue
*
* queue.open();
*
* // create an iteration over 20 random Integers (between 0 and 100)
*
* Cursor<Integer> cursor = new DiscreteRandomNumber(new JavaDiscreteRandomWrapper(100), 20);
*
* // insert all elements of the given iterator
*
* for (; cursor.hasNext(); queue.enqueue(cursor.next()));
*
* // print all elements of the queue
*
* while (!queue.isEmpty())
* System.out.println(queue.dequeue());
*
* System.out.println();
*
* // close open queue and cursor after use
*
* queue.close();
* cursor.close();
* </pre>
*
* Usage example (2).
* <pre>
* // create an iteration over the Integer between 0 and 19
*
* cursor = new Enumerator(20);
*
* // create a new stack queue that uses a new stack to store its
* // elements and that contains all elements of the given iterator
*
* queue = new StackQueue<Integer>();
* Queues.enqueueAll(queue, cursor);
*
* // open the queue
*
* queue.open();
*
* // print all elements of the queue
*
* while (!queue.isEmpty())
* System.out.println(queue.dequeue());
*
* System.out.println();
*
* // close open queue and cursor after use
*
* queue.close();
* cursor.close();
* </pre>
*
* @param <E> the type of the elements of this queue.
* @see xxl.core.collections.queues.Queue
* @see xxl.core.collections.queues.AbstractQueue
* @see xxl.core.collections.queues.LIFOQueue
* @see java.util.Stack
*/
public class StackQueue<E> extends AbstractQueue<E> implements LIFOQueue<E> {
/**
* A factory method to create a new StackQueue (see contract for
* {@link Queue#FACTORY_METHOD FACTORY_METHOD} in interface Queue).
* It may be invoked with a <i>parameter list</i> (for
* further details see Function) of stacks, an iterator or without any
* parameters. A <i>parameter list</i> of stacks will be used
* to initialize the internally used stack with the stack at index 0
* and an iterator will be used to insert the contained elements into
* the new StackQueue.
*
* @see Function
*/
public static final Function<Object, StackQueue<Object>> FACTORY_METHOD = new AbstractFunction<Object,StackQueue<Object>>() {
@Override
public StackQueue<Object> invoke() {
return new StackQueue<Object>();
}
@Override
public StackQueue<Object> invoke(Object iterator) {
StackQueue<Object> queue = new StackQueue<Object>();
for (Iterator i = (Iterator)iterator; i.hasNext(); queue.enqueue(i.next()));
return queue;
}
@Override
public StackQueue<Object> invoke(List<? extends Object> list) {
return new StackQueue<Object>(
(Stack<Object>)list.get(0)
);
}
};
/**
* The stack is internally used to store the elements of the queue.
*/
protected Stack<E> stack;
/**
* Constructs a queue containing the elements of the stack. The
* specified stack is internally used to store the elements of the
* queue.
*
* @param stack the stack that is used to initialize the internally
* used stack.
*/
public StackQueue(Stack<E> stack) {
this.stack = stack;
}
/**
* Constructs an empty queue. This queue instantiates a new stack in
* order to store its elements.
*/
public StackQueue() {
this(new Stack<E>());
}
/**
* Appends the specified element to the <i>end</i> of this queue.
*
* @param object element to be appended to the <i>end</i> of this
* queue.
*/
@Override
protected void enqueueObject(E object) {
stack.push(object);
}
/**
* Returns the <i>next</i> element in the queue <i>without</i> removing it.
*
* @return the <i>next</i> element in the queue.
*/
@Override
protected E peekObject() {
return stack.peek();
}
/**
* Returns the <i>next</i> element in the queue and <i>removes</i> it.
*
* @return the <i>next</i> element in the queue.
*/
@Override
protected E dequeueObject() {
return stack.pop();
}
/**
* Removes all elements from this queue. The queue will be
* empty after this call returns so that <tt>size() == 0</tt>.
*/
@Override
public void clear () {
stack.clear();
size = 0;
}
}