    001/**
    002 * ========================================
    003 * JCommon : a free Java report library
    004 * ========================================
    005 *
    006 * Project Info:  http://www.jfree.org/jcommon/
    007 *
    008 * (C) Copyright 2000-2006, by Object Refinery Limited and Contributors.
    009 *
    010 * This library is free software; you can redistribute it and/or modify it under the terms
    011 * of the GNU Lesser General Public License as published by the Free Software Foundation;
    012 * either version 2.1 of the License, or (at your option) any later version.
    013 *
    014 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
    015 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    016 * See the GNU Lesser General Public License for more details.
    017 *
    018 * You should have received a copy of the GNU Lesser General Public License along with this
    019 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
    020 * Boston, MA 02111-1307, USA.
    021 *
    022 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
    023 * in the United States and other countries.]
    024 *
    025 * ------------
    026 * $Id: FastStack.java,v 1.3 2008/09/10 09:22:05 mungady Exp $
    027 * ------------
    028 * (C) Copyright 2002-2006, by Object Refinery Limited.
    029 */
    030
    031package org.jfree.util;
    032
    033import java.io.Serializable;
    034import java.util.Arrays;
    035import java.util.EmptyStackException;
    036
    037/**
    038 * A very simple unsynchronized stack. This one is faster than the
    039 * java.util-Version.
    040 *
    041 * @author Thomas Morgner
    042 */
    043public final class FastStack implements Serializable, Cloneable {
    044    private Object[] contents;
    045    private int size;
    046    private int initialSize;
    047
    048    /**
    049     * Creates a new empty stack.
    050     */
    051    public FastStack() {
    052        this.initialSize = 10;
    053    }
    054
    055    /**
    056     * Creates a new empty stack with the specified initial storage size.
    057     *
    058     * @param size  the initial storage elements.
    059     */
    060    public FastStack(int size) {
    061        this.initialSize = Math.max(1, size);
    062    }
    063
    064    /**
    065     * Returns <code>true</code> if the stack is empty, and <code>false</code>
    066     * otherwise.
    067     *
    068     * @return A boolean.
    069     */
    070    public boolean isEmpty() {
    071        return this.size == 0;
    072    }
    073
    074    /**
    075     * Returns the number of elements in the stack.
    076     *
    077     * @return The element count.
    078     */
    079    public int size() {
    080        return this.size;
    081    }
    082
    083    /**
    084     * Pushes an object onto the stack.
    085     *
    086     * @param o  the object.
    087     */
    088    public void push(Object o) {
    089        if (this.contents == null) {
    090            this.contents = new Object[this.initialSize];
    091            this.contents[0] = o;
    092            this.size = 1;
    093            return;
    094        }
    095
    096        final int oldSize = this.size;
    097        this.size += 1;
    098        if (this.contents.length == this.size) {
    099            // grow ..
    100            final Object[] newContents = new Object[this.size
    101                    + this.initialSize];
    102            System.arraycopy(this.contents, 0, newContents, 0, this.size);
    103            this.contents = newContents;
    104        }
    105        this.contents[oldSize] = o;
    106    }
    107
    108    /**
    109     * Returns the object at the top of the stack without removing it.
    110     *
    111     * @return The object at the top of the stack.
    112     */
    113    public Object peek() {
    114        if (this.size == 0) {
    115            throw new EmptyStackException();
    116        }
    117        return this.contents[this.size - 1];
    118    }
    119
    120    /**
    121     * Removes and returns the object from the top of the stack.
    122     *
    123     * @return The object.
    124     */
    125    public Object pop() {
    126        if (this.size == 0) {
    127            throw new EmptyStackException();
    128        }
    129        this.size -= 1;
    130        final Object retval = this.contents[this.size];
    131        this.contents[this.size] = null;
    132        return retval;
    133    }
    134
    135    /**
    136     * Returns a clone of the stack.
    137     *
    138     * @return A clone.
    139     */
    140    public Object clone() {
    141        try {
    142            FastStack stack = (FastStack) super.clone();
    143            if (this.contents != null) {
    144                stack.contents = (Object[]) this.contents.clone();
    145            }
    146            return stack;
    147        }
    148        catch (CloneNotSupportedException cne) {
    149            throw new IllegalStateException("Clone not supported? Why?");
    150        }
    151    }
    152
    153    /**
    154     * Clears the stack.
    155     */
    156    public void clear() {
    157        this.size = 0;
    158        if (this.contents != null) {
    159            Arrays.fill(this.contents, null);
    160        }
    161    }
    162
    163    /**
    164     * Returns the item at the specified slot in the stack.
    165     *
    166     * @param index  the index.
    167     *
    168     * @return The item.
    169     */
    170    public Object get(final int index) {
    171        if (index >= this.size) {
    172            throw new IndexOutOfBoundsException();
    173        }
    174        return this.contents[index];
    175    }
    176}