001 /*
002 * Copyright (c) Andrey Kuznetsov. All Rights Reserved.
003 *
004 * Redistribution and use in source and binary forms, with or without
005 * modification, are permitted provided that the following conditions are met:
006 *
007 * o Redistributions of source code must retain the above copyright notice,
008 * this list of conditions and the following disclaimer.
009 *
010 * o Redistributions in binary form must reproduce the above copyright notice,
011 * this list of conditions and the following disclaimer in the documentation
012 * and/or other materials provided with the distribution.
013 *
014 * o Neither the name of imagero Andrey Kuznetsov nor the names of
015 * its contributors may be used to endorse or promote products derived
016 * from this software without specific prior written permission.
017 *
018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030
031 package com.imagero.util;
032
033 import java.util.EmptyStackException;
034 import java.util.Enumeration;
035
036 /**
037 * Minimal Vector implementation without synchronization
038 */
039 public final class Vector {
040
041 Object[] elements;
042
043 int size;
044 int startSize;
045
046
047 public Vector() {
048 this(3);
049 }
050
051 public Vector(int size) {
052 this.startSize = size;
053 this.elements = new Object[size];
054 }
055
056 public void add(Object item) {
057 checkSize(size + 1);
058 elements[size++] = item;
059 }
060
061 public void insert(Object item, int pos) {
062 checkSize(size + 1);
063 System.arraycopy(elements, pos, elements, pos + 1, size - pos);
064 elements[pos] = item;
065 size++;
066 }
067
068 public Object pop() {
069 if (size > 0) {
070 size--;
071 Object obj = elements[size];
072 elements[size] = null;
073 return obj;
074 }
075 throw new EmptyStackException();
076 }
077
078 public Object peek() {
079 if (size > 0) {
080 Object obj = elements[size - 1];
081 return obj;
082 }
083 throw new EmptyStackException();
084 }
085
086 public int indexOf(Object o) {
087 if (o != null) {
088 for (int i = 0; i < size; i++) {
089 if (elements[i] != null && elements[i].equals(o)) {
090 return i;
091 }
092 }
093 }
094 return -1;
095 }
096
097 public boolean contains(Object o) {
098 return indexOf(o) >= 0;
099 }
100
101 public boolean remove(Object o) {
102 int index = indexOf(o);
103 if (index >= 0) {
104 remove(index);
105 }
106 return index >= 0;
107 }
108
109 public Object remove(int index) {
110 if (index >= 0 && index < size) {
111 Object obj = elements[index];
112 int length = size - index - 1;
113 if (length > 0) {
114 System.arraycopy(elements, index + 1, elements, index, length);
115 elements[size] = null;
116 }
117 size--;
118 return obj;
119 } else {
120 throw new IndexOutOfBoundsException("" + index);
121 }
122 }
123
124 public void remove(int from, int count) {
125 if (from >= 0 && from + count <= size) {
126 int length = size - (from + count) - 1;
127 if (length > 0) {
128 System.arraycopy(elements, from + count + 1, elements, from, length);
129 }
130 size -= count;
131 for (int i = 0; i < length; i++) {
132 elements[size + i] = null;
133 }
134 } else {
135 throw new IndexOutOfBoundsException("" + from);
136 }
137 }
138
139 public Object elementAt(int index) {
140 if (index >= 0 && index < size) {
141 Object obj = elements[index];
142 return obj;
143 } else {
144 throw new IndexOutOfBoundsException("" + index);
145 }
146 }
147
148 /**
149 * replace element at given index.
150 * @param index element index
151 * @param o Object
152 * @return replaced Object
153 */
154 public Object setElementAt(int index, Object o) {
155 if (index >= 0 && index < size) {
156 Object tmp = elements[index];
157 elements[index] = o;
158 return tmp;
159 } else {
160 throw new IndexOutOfBoundsException("" + index);
161 }
162 }
163
164 public int getCount() {
165 return size;
166 }
167
168 public int size() {
169 return size;
170 }
171
172 public boolean isEmpty() {
173 return size == 0;
174 }
175
176 private void checkSize(int minSize) {
177 if (minSize > elements.length) {
178 Object oldData[] = elements;
179 elements = new Object[Math.max(minSize + 10, elements.length * 2)];
180 System.arraycopy(oldData, 0, elements, 0, size);
181 }
182 }
183
184 public Enumeration elements() {
185 return new Enumeration() {
186 int pos;
187
188 public boolean hasMoreElements() {
189 return pos < getCount();
190 }
191
192 public Object nextElement() {
193 if (hasMoreElements()) {
194 return elements[pos++];
195 } else {
196 throw new IndexOutOfBoundsException();
197 }
198 }
199 };
200 }
201
202 public int getCount(Class c) {
203 int count = 0;
204 for (int i = 0; i < elements.length; i++) {
205 if (c.isInstance(elements[i])) {
206 count++;
207 }
208 }
209 return count;
210 }
211
212 public void clear() {
213 elements = new Object[startSize];
214 size = 0;
215 }
216
217 public void toArray(Object[] dest) {
218 System.arraycopy(elements, 0, dest, 0, Math.min(size, dest.length));
219 }
220 }