1 | /*
|
---|
2 | * This program is free software; you can redistribute it and/or modify
|
---|
3 | * it under the terms of the GNU General Public License as published by
|
---|
4 | * the Free Software Foundation; either version 2 of the License, or
|
---|
5 | * (at your option) any later version.
|
---|
6 | *
|
---|
7 | * This program is distributed in the hope that it will be useful,
|
---|
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
10 | * GNU General Public License for more details.
|
---|
11 | *
|
---|
12 | * You should have received a copy of the GNU General Public License
|
---|
13 | * along with this program; if not, write to the Free Software
|
---|
14 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
---|
15 | */
|
---|
16 |
|
---|
17 | /*
|
---|
18 | * FastVector.java
|
---|
19 | * Copyright (C) 1999 Eibe Frank
|
---|
20 | *
|
---|
21 | */
|
---|
22 |
|
---|
23 | package weka.core;
|
---|
24 |
|
---|
25 | import java.util.*;
|
---|
26 | import java.io.*;
|
---|
27 |
|
---|
28 | /**
|
---|
29 | * Implements a fast vector class without synchronized
|
---|
30 | * methods. Replaces java.util.Vector. (Synchronized methods tend to
|
---|
31 | * be slow.)
|
---|
32 | *
|
---|
33 | * @author Eibe Frank ([email protected])
|
---|
34 | * @version $Revision: 8815 $ */
|
---|
35 | public class FastVector implements Copyable, Serializable {
|
---|
36 |
|
---|
37 | /**
|
---|
38 | * Class for enumerating the vector's elements.
|
---|
39 | */
|
---|
40 | public class FastVectorEnumeration implements Enumeration {
|
---|
41 |
|
---|
42 | /** The counter. */
|
---|
43 | private int m_Counter;
|
---|
44 |
|
---|
45 | /** The vector. */
|
---|
46 | private FastVector m_Vector;
|
---|
47 |
|
---|
48 | /** Special element. Skipped during enumeration. */
|
---|
49 | private int m_SpecialElement;
|
---|
50 |
|
---|
51 | /**
|
---|
52 | * Constructs an enumeration.
|
---|
53 | *
|
---|
54 | * @param vector the vector which is to be enumerated
|
---|
55 | */
|
---|
56 | public FastVectorEnumeration(FastVector vector) {
|
---|
57 |
|
---|
58 | m_Counter = 0;
|
---|
59 | m_Vector = vector;
|
---|
60 | m_SpecialElement = -1;
|
---|
61 | }
|
---|
62 |
|
---|
63 | /**
|
---|
64 | * Constructs an enumeration with a special element.
|
---|
65 | * The special element is skipped during the enumeration.
|
---|
66 | *
|
---|
67 | * @param vector the vector which is to be enumerated
|
---|
68 | * @param special the index of the special element
|
---|
69 | */
|
---|
70 | public FastVectorEnumeration(FastVector vector, int special) {
|
---|
71 |
|
---|
72 | m_Vector = vector;
|
---|
73 | m_SpecialElement = special;
|
---|
74 | if (special == 0) {
|
---|
75 | m_Counter = 1;
|
---|
76 | } else {
|
---|
77 | m_Counter = 0;
|
---|
78 | }
|
---|
79 | }
|
---|
80 |
|
---|
81 |
|
---|
82 | /**
|
---|
83 | * Tests if there are any more elements to enumerate.
|
---|
84 | *
|
---|
85 | * @return true if there are some elements left
|
---|
86 | */
|
---|
87 | public final boolean hasMoreElements() {
|
---|
88 |
|
---|
89 | if (m_Counter < m_Vector.size()) {
|
---|
90 | return true;
|
---|
91 | }
|
---|
92 | return false;
|
---|
93 | }
|
---|
94 |
|
---|
95 | /**
|
---|
96 | * Returns the next element.
|
---|
97 | *
|
---|
98 | * @return the next element to be enumerated
|
---|
99 | */
|
---|
100 | public final Object nextElement() {
|
---|
101 |
|
---|
102 | Object result = m_Vector.elementAt(m_Counter);
|
---|
103 |
|
---|
104 | m_Counter++;
|
---|
105 | if (m_Counter == m_SpecialElement) {
|
---|
106 | m_Counter++;
|
---|
107 | }
|
---|
108 | return result;
|
---|
109 | }
|
---|
110 | }
|
---|
111 |
|
---|
112 | /** The array of objects. */
|
---|
113 | private Object[] m_Objects;
|
---|
114 |
|
---|
115 | /** The current size; */
|
---|
116 | private int m_Size;
|
---|
117 |
|
---|
118 | /** The capacity increment */
|
---|
119 | private int m_CapacityIncrement;
|
---|
120 |
|
---|
121 | /** The capacity multiplier. */
|
---|
122 | private double m_CapacityMultiplier;
|
---|
123 |
|
---|
124 | /**
|
---|
125 | * Constructs an empty vector with initial
|
---|
126 | * capacity zero.
|
---|
127 | */
|
---|
128 | public FastVector() {
|
---|
129 |
|
---|
130 | m_Objects = new Object[0];
|
---|
131 | m_Size = 0;
|
---|
132 | m_CapacityIncrement = 1;
|
---|
133 | m_CapacityMultiplier = 2;
|
---|
134 | }
|
---|
135 |
|
---|
136 | /**
|
---|
137 | * Constructs a vector with the given capacity.
|
---|
138 | *
|
---|
139 | * @param capacity the vector's initial capacity
|
---|
140 | */
|
---|
141 | public FastVector(int capacity) {
|
---|
142 |
|
---|
143 | m_Objects = new Object[capacity];
|
---|
144 | m_Size = 0;
|
---|
145 | m_CapacityIncrement = 1;
|
---|
146 | m_CapacityMultiplier = 2;
|
---|
147 | }
|
---|
148 |
|
---|
149 | /**
|
---|
150 | * Constructs a vector with the given capacity, capacity
|
---|
151 | * increment and capacity mulitplier.
|
---|
152 | *
|
---|
153 | * @param capacity the vector's initial capacity
|
---|
154 | */
|
---|
155 | public FastVector(int capacity, int capIncrement,
|
---|
156 | double capMultiplier) {
|
---|
157 |
|
---|
158 | m_Objects = new Object[capacity];
|
---|
159 | m_Size = 0;
|
---|
160 | m_CapacityIncrement = capIncrement;
|
---|
161 | m_CapacityMultiplier = capMultiplier;
|
---|
162 | }
|
---|
163 |
|
---|
164 | /**
|
---|
165 | * Adds an element to this vector. Increases its
|
---|
166 | * capacity if its not large enough.
|
---|
167 | *
|
---|
168 | * @param element the element to add
|
---|
169 | */
|
---|
170 | public final void addElement(Object element) {
|
---|
171 |
|
---|
172 | Object[] newObjects;
|
---|
173 |
|
---|
174 | if (m_Size == m_Objects.length) {
|
---|
175 | newObjects = new Object[(int)m_CapacityMultiplier *
|
---|
176 | (m_Objects.length +
|
---|
177 | m_CapacityIncrement)];
|
---|
178 | System.arraycopy(m_Objects, 0, newObjects, 0, m_Size);
|
---|
179 | m_Objects = newObjects;
|
---|
180 | }
|
---|
181 | m_Objects[m_Size] = element;
|
---|
182 | m_Size++;
|
---|
183 | }
|
---|
184 |
|
---|
185 | /**
|
---|
186 | * Returns the capacity of the vector.
|
---|
187 | *
|
---|
188 | * @return the capacity of the vector
|
---|
189 | */
|
---|
190 | public final int capacity() {
|
---|
191 |
|
---|
192 | return m_Objects.length;
|
---|
193 | }
|
---|
194 |
|
---|
195 | /**
|
---|
196 | * Produces a shallow copy of this vector.
|
---|
197 | *
|
---|
198 | * @return the new vector
|
---|
199 | */
|
---|
200 | public final Object copy() {
|
---|
201 |
|
---|
202 | FastVector copy = new FastVector(m_Objects.length,
|
---|
203 | m_CapacityIncrement,
|
---|
204 | m_CapacityMultiplier);
|
---|
205 | copy.m_Size = m_Size;
|
---|
206 | System.arraycopy(m_Objects, 0, copy.m_Objects, 0, m_Size);
|
---|
207 | return copy;
|
---|
208 | }
|
---|
209 |
|
---|
210 | /**
|
---|
211 | * Clones the vector and shallow copies all its elements.
|
---|
212 | * The elements have to implement the Copyable interface.
|
---|
213 | *
|
---|
214 | * @return the new vector
|
---|
215 | */
|
---|
216 | public final Object copyElements() {
|
---|
217 |
|
---|
218 | FastVector copy = new FastVector(m_Objects.length,
|
---|
219 | m_CapacityIncrement,
|
---|
220 | m_CapacityMultiplier);
|
---|
221 | copy.m_Size = m_Size;
|
---|
222 | for (int i = 0; i < m_Size; i++) {
|
---|
223 | copy.m_Objects[i] = ((Copyable)m_Objects[i]).copy();
|
---|
224 | }
|
---|
225 | return copy;
|
---|
226 | }
|
---|
227 |
|
---|
228 | /**
|
---|
229 | * Returns the element at the given position.
|
---|
230 | *
|
---|
231 | * @param index the element's index
|
---|
232 | * @return the element with the given index
|
---|
233 | */
|
---|
234 | public final Object elementAt(int index) {
|
---|
235 |
|
---|
236 | return m_Objects[index];
|
---|
237 | }
|
---|
238 |
|
---|
239 | /**
|
---|
240 | * Returns an enumeration of this vector.
|
---|
241 | *
|
---|
242 | * @return an enumeration of this vector
|
---|
243 | */
|
---|
244 | public final Enumeration elements() {
|
---|
245 |
|
---|
246 | return new FastVectorEnumeration(this);
|
---|
247 | }
|
---|
248 |
|
---|
249 | /**
|
---|
250 | * Returns an enumeration of this vector, skipping the
|
---|
251 | * element with the given index.
|
---|
252 | *
|
---|
253 | * @param index the element to skip
|
---|
254 | * @return an enumeration of this vector
|
---|
255 | */
|
---|
256 | public final Enumeration elements(int index) {
|
---|
257 |
|
---|
258 | return new FastVectorEnumeration(this, index);
|
---|
259 | }
|
---|
260 |
|
---|
261 | /**
|
---|
262 | * Returns the first element of the vector.
|
---|
263 | *
|
---|
264 | * @return the first element of the vector
|
---|
265 | */
|
---|
266 | public final Object firstElement() {
|
---|
267 |
|
---|
268 | return m_Objects[0];
|
---|
269 | }
|
---|
270 |
|
---|
271 | /**
|
---|
272 | * Searches for the first occurence of the given argument,
|
---|
273 | * testing for equality using the equals method.
|
---|
274 | *
|
---|
275 | * @param element the element to be found
|
---|
276 | * @return the index of the first occurrence of the argument
|
---|
277 | * in this vector; returns -1 if the object is not found
|
---|
278 | */
|
---|
279 | public final int indexOf(Object element) {
|
---|
280 |
|
---|
281 | for (int i = 0; i < m_Size; i++) {
|
---|
282 | if (element.equals(m_Objects[i])) {
|
---|
283 | return i;
|
---|
284 | }
|
---|
285 | }
|
---|
286 | return -1;
|
---|
287 | }
|
---|
288 |
|
---|
289 | /**
|
---|
290 | * Inserts an element at the given position.
|
---|
291 | *
|
---|
292 | * @param element the element to be inserted
|
---|
293 | * @param index the element's index
|
---|
294 | */
|
---|
295 | public final void insertElementAt(Object element, int index) {
|
---|
296 |
|
---|
297 | Object[] newObjects;
|
---|
298 |
|
---|
299 | if (m_Size < m_Objects.length) {
|
---|
300 | System.arraycopy(m_Objects, index, m_Objects, index + 1,
|
---|
301 | m_Size - index);
|
---|
302 | m_Objects[index] = element;
|
---|
303 | } else {
|
---|
304 | newObjects = new Object[(int)m_CapacityMultiplier *
|
---|
305 | (m_Objects.length +
|
---|
306 | m_CapacityIncrement)];
|
---|
307 | System.arraycopy(m_Objects, 0, newObjects, 0, index);
|
---|
308 | newObjects[index] = element;
|
---|
309 | System.arraycopy(m_Objects, index, newObjects, index + 1,
|
---|
310 | m_Size - index);
|
---|
311 | m_Objects = newObjects;
|
---|
312 | }
|
---|
313 | m_Size++;
|
---|
314 | }
|
---|
315 |
|
---|
316 | /**
|
---|
317 | * Returns the last element of the vector.
|
---|
318 | *
|
---|
319 | * @return the last element of the vector
|
---|
320 | */
|
---|
321 | public final Object lastElement() {
|
---|
322 |
|
---|
323 | return m_Objects[m_Size - 1];
|
---|
324 | }
|
---|
325 |
|
---|
326 | /**
|
---|
327 | * Deletes an element from this vector.
|
---|
328 | *
|
---|
329 | * @param index the index of the element to be deleted
|
---|
330 | */
|
---|
331 | public final void removeElementAt(int index) {
|
---|
332 |
|
---|
333 | System.arraycopy(m_Objects, index + 1, m_Objects, index,
|
---|
334 | m_Size - index - 1);
|
---|
335 | m_Size--;
|
---|
336 | }
|
---|
337 |
|
---|
338 | /**
|
---|
339 | * Removes all components from this vector and sets its
|
---|
340 | * size to zero.
|
---|
341 | */
|
---|
342 | public final void removeAllElements() {
|
---|
343 |
|
---|
344 | m_Objects = new Object[m_Objects.length];
|
---|
345 | m_Size = 0;
|
---|
346 | }
|
---|
347 |
|
---|
348 | /**
|
---|
349 | * Appends all elements of the supplied vector to this vector.
|
---|
350 | *
|
---|
351 | * @param toAppend the FastVector containing elements to append.
|
---|
352 | */
|
---|
353 | public final void appendElements(FastVector toAppend) {
|
---|
354 |
|
---|
355 | setCapacity(size() + toAppend.size());
|
---|
356 | System.arraycopy(toAppend.m_Objects, 0, m_Objects, size(), toAppend.size());
|
---|
357 | m_Size = m_Objects.length;
|
---|
358 | }
|
---|
359 |
|
---|
360 | /**
|
---|
361 | * Returns all the elements of this vector as an array
|
---|
362 | *
|
---|
363 | * @param an array containing all the elements of this vector
|
---|
364 | */
|
---|
365 | public final Object [] toArray() {
|
---|
366 |
|
---|
367 | Object [] newObjects = new Object[size()];
|
---|
368 | System.arraycopy(m_Objects, 0, newObjects, 0, size());
|
---|
369 | return newObjects;
|
---|
370 | }
|
---|
371 |
|
---|
372 | /**
|
---|
373 | * Sets the vector's capacity to the given value.
|
---|
374 | *
|
---|
375 | * @param capacity the new capacity
|
---|
376 | */
|
---|
377 | public final void setCapacity(int capacity) {
|
---|
378 |
|
---|
379 | Object[] newObjects = new Object[capacity];
|
---|
380 |
|
---|
381 | System.arraycopy(m_Objects, 0, newObjects, 0, Math.min(capacity, m_Size));
|
---|
382 | m_Objects = newObjects;
|
---|
383 | if (m_Objects.length < m_Size)
|
---|
384 | m_Size = m_Objects.length;
|
---|
385 | }
|
---|
386 |
|
---|
387 | /**
|
---|
388 | * Sets the element at the given index.
|
---|
389 | *
|
---|
390 | * @param element the element to be put into the vector
|
---|
391 | * @param index the index at which the element is to be placed
|
---|
392 | */
|
---|
393 | public final void setElementAt(Object element, int index) {
|
---|
394 |
|
---|
395 | m_Objects[index] = element;
|
---|
396 | }
|
---|
397 |
|
---|
398 | /**
|
---|
399 | * Returns the vector's current size.
|
---|
400 | *
|
---|
401 | * @return the vector's current size
|
---|
402 | */
|
---|
403 | public final int size() {
|
---|
404 |
|
---|
405 | return m_Size;
|
---|
406 | }
|
---|
407 |
|
---|
408 | /**
|
---|
409 | * Swaps two elements in the vector.
|
---|
410 | *
|
---|
411 | * @param first index of the first element
|
---|
412 | * @param second index of the second element
|
---|
413 | */
|
---|
414 | public final void swap(int first, int second) {
|
---|
415 |
|
---|
416 | Object help = m_Objects[first];
|
---|
417 |
|
---|
418 | m_Objects[first] = m_Objects[second];
|
---|
419 | m_Objects[second] = help;
|
---|
420 | }
|
---|
421 |
|
---|
422 | /**
|
---|
423 | * Sets the vector's capacity to its size.
|
---|
424 | */
|
---|
425 | public final void trimToSize() {
|
---|
426 |
|
---|
427 | Object[] newObjects = new Object[m_Size];
|
---|
428 |
|
---|
429 | System.arraycopy(m_Objects, 0, newObjects, 0, m_Size);
|
---|
430 | m_Objects = newObjects;
|
---|
431 | }
|
---|
432 | }
|
---|