Source code: javax/ide/extension/spi/Stack.java
1 package javax.ide.extension.spi;
2
3 import java.util.AbstractCollection;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.Collections;
7 import java.util.Iterator;
8 import java.util.List;
9 import java.util.ListIterator;
10
11 /**
12 * Convenient implementation of a Last In First Out (LIFO) stack. This
13 * implementation differs from the one in java.util.Stack in two ways.
14 *
15 * First, like most of the collection APIs, it is unsynchronized for better
16 * performance when synchronization is not required. If a synchronized stack
17 * is required, you can use the
18 * {@link java.util.Collections#synchronizedCollection(java.util.Collection) Collections.synchronizedCollection()}
19 * method to retrieve a synchronized instance.
20 *
21 * Second, it does not expose its internal implementation via its superclass.
22 * Extending <tt>AbstractCollection</tt> instead of <tt>Vector</tt> allows
23 * objects of this class to be used interchangably with other collection
24 * framework classes without exposing its internal implementation.
25 *
26 * @author Brian.Duff@oracle.com
27 */
28 public final class Stack extends AbstractCollection
29 {
30 private ArrayList _list;
31
32 /**
33 * Construct a stack with no additional arguments.
34 */
35 public Stack()
36 {
37 }
38
39 /**
40 * Construct a stack initialized to contain all the items in the specified
41 * collection. The items will be pushed on to the stack in their order in
42 * the collection.
43 *
44 * @param c a collection of items to push onto the stack.
45 */
46 public Stack( Collection c )
47 {
48 addAll( c );
49 }
50
51
52 /**
53 * Gets (or lazily instantiates) the list implementation used by this stack.
54 *
55 * @return a list.
56 */
57 private List getList()
58 {
59 if ( _list == null )
60 {
61 _list = new ArrayList();
62 }
63 return _list;
64 }
65
66 /**
67 * Gets whether there are more elements on the stack.
68 *
69 * @return true if there are no more elements on the stack.
70 */
71 public boolean isEmpty()
72 {
73 return _list == null || _list.isEmpty();
74 }
75
76 /**
77 * Pushes an element onto the stack.
78 *
79 * @param o an element to push onto the stack
80 * @return true if the stack changed as a result of this operation.
81 */
82 public boolean push( Object o )
83 {
84 return getList().add( o );
85 }
86
87 /**
88 * Obtains the top element on the stack without removing it.
89 *
90 * @return the top element on the stack.
91 */
92 public Object peek()
93 {
94 if ( isEmpty() )
95 {
96 throw new IllegalStateException( "Illegal peek()" ); // NOTRANS
97 }
98 List l = getList();
99 return l.get( l.size() - 1 );
100 }
101
102 /**
103 * Replaces the top of the stack with the specified object.
104 *
105 * @param o the object to replace the top of the stack with.
106 */
107 public void replace( Object o )
108 {
109 if ( isEmpty() )
110 {
111 throw new IllegalStateException( "Illegal replace()" ); // NOTRANS
112 }
113
114 List l = getList();
115 l.set( l.size() - 1, o );
116 }
117
118 /**
119 * Pops the top element off the stack and returns it.
120 *
121 * @return the old top element
122 */
123 public Object pop()
124 {
125 if ( isEmpty() )
126 {
127 throw new IllegalStateException( "Illegal pop()" ); // NOTRANS
128 }
129 List l = getList();
130 int lastIndex = l.size() -1 ;
131
132 Object theValue = l.get( lastIndex );
133 l.remove( lastIndex );
134
135 if ( l.isEmpty() )
136 {
137 _list = null;
138 }
139
140 return theValue;
141 }
142
143 /**
144 * Gets an iterator for elements on the stack. This iterator starts at the
145 * bottom of the stack and proceeds to the top.
146 *
147 * @return an iterator over stack elements.
148 */
149 public Iterator reverseIterator()
150 {
151 if ( isEmpty() )
152 {
153 return Collections.EMPTY_LIST.iterator();
154 }
155 return _list.iterator();
156 }
157
158
159
160
161 // java.util.Collection implementation
162
163 public boolean add( Object o )
164 {
165 return push( o );
166 }
167
168 public void clear()
169 {
170 getList().clear();
171 }
172
173 /**
174 * Gets an iterator for elements on the stack. The iterator starts at the
175 * top of the stack and proceeds to the bottom of the stack.
176 *
177 * @return an iterator over stack elements.
178 */
179 public Iterator iterator()
180 {
181 if ( isEmpty() )
182 {
183 return Collections.EMPTY_LIST.iterator();
184 }
185
186 return new ReverseListIterator( _list );
187 }
188
189 public int size()
190 {
191 return getList().size();
192 }
193
194 /**
195 * Iterator that traverses a list in reverse order. It does this by just
196 * adapting the ListIterator of the list.
197 */
198 private final static class ReverseListIterator
199 implements Iterator
200 {
201 private final ListIterator _listIterator;
202
203 public ReverseListIterator( List list )
204 {
205 _listIterator = list.listIterator( list.size() );
206 }
207
208 public boolean hasNext()
209 {
210 return _listIterator.hasPrevious();
211 }
212
213 public Object next()
214 {
215 return _listIterator.previous();
216 }
217
218 public void remove()
219 {
220 _listIterator.remove();
221 }
222
223 }
224 }