/* * Copyright 2005 by Oracle USA * 500 Oracle Parkway, Redwood Shores, California, 94065, U.S.A. * All rights reserved. */ package javax.ide.extension.spi; import java.util.AbstractCollection; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** * Convenient implementation of a Last In First Out (LIFO) stack. This * implementation differs from the one in java.util.Stack in two ways. * * First, like most of the collection APIs, it is unsynchronized for better * performance when synchronization is not required. If a synchronized stack * is required, you can use the * {@link java.util.Collections#synchronizedCollection(java.util.Collection) Collections.synchronizedCollection()} * method to retrieve a synchronized instance. * * Second, it does not expose its internal implementation via its superclass. * Extending AbstractCollection instead of Vector allows * objects of this class to be used interchangably with other collection * framework classes without exposing its internal implementation. * * @author Brian.Duff@oracle.com */ public final class Stack extends AbstractCollection implements Iterable { private ArrayList _list; /** * Construct a stack with no additional arguments. */ public Stack() { } /** * Construct a stack initialized to contain all the items in the specified * collection. The items will be pushed on to the stack in their order in * the collection. * * @param c a collection of items to push onto the stack. */ public Stack( Collection c ) { addAll( c ); } /** * Gets (or lazily instantiates) the list implementation used by this stack. * * @return a list. */ private List getList() { if ( _list == null ) { _list = new ArrayList(); } return _list; } /** * Gets whether there are more elements on the stack. * * @return true if there are no more elements on the stack. */ public boolean isEmpty() { return size() == 0; } /** * Pushes an element onto the stack. * * @param o an element to push onto the stack * @return true if the stack changed as a result of this operation. */ public boolean push( T o ) { return getList().add( o ); } /** * Obtains the top element on the stack without removing it. * * @return the top element on the stack. */ public T peek() { int size = size(); if ( size == 0 ) { throw new IllegalStateException( "Illegal peek()" ); // NOTRANS } return getList().get( size - 1 ); } /** * Replaces the top of the stack with the specified object. * * @param o the object to replace the top of the stack with. */ public void replace( T o ) { int size = size(); if ( size == 0 ) { throw new IllegalStateException( "Illegal replace()" ); // NOTRANS } getList().set( size - 1, o ); } /** * Pops the top element off the stack and returns it. * * @return the old top element */ public T pop() { int size = size(); if ( size == 0 ) { throw new IllegalStateException( "Illegal pop()" ); // NOTRANS } T theValue = _list.remove( size-1 ); if ( size == 1 ) // i.e. we removed the last remaining single item { _list = null; } return theValue; } /** * Gets an iterator for elements on the stack. This iterator starts at the * bottom of the stack and proceeds to the top. * * @return an iterator over stack elements. */ public Iterator reverseIterator() { if ( isEmpty() ) { // Do not remove this cast. Eclipse compiler fails without it. return (Iterator)Collections.emptyList().iterator(); } return _list.iterator(); } // java.util.Collection implementation public boolean add( T o ) { return push( o ); } public void clear() { if ( _list != null ) { _list.clear(); } } /** * Gets an iterator for elements on the stack. The iterator starts at the * top of the stack and proceeds to the bottom of the stack. * * @return an iterator over stack elements. */ public Iterator iterator() { if ( isEmpty() ) { return Collections.EMPTY_LIST.iterator(); } return new ReverseListIterator( _list ); } public int size() { return _list == null ? 0 : _list.size(); } /** * Iterator that traverses a list in reverse order. It does this by just * adapting the ListIterator of the list. */ private final static class ReverseListIterator implements Iterator { private final ListIterator _listIterator; public ReverseListIterator( List list ) { _listIterator = list.listIterator( list.size() ); } public boolean hasNext() { return _listIterator.hasPrevious(); } public T next() { return _listIterator.previous(); } public void remove() { _listIterator.remove(); } } }