    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
    031    package org.jfree.util;
    032
    033    import java.io.Serializable;
    034    import java.util.Arrays;
    035    import 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     */
    043    public 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    }