1 /*
2 * Copyright 2001-2010 Stephen Colebourne
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.joda.primitives.collection.impl;
17
18 import java.util.Collection;
19 import java.util.Iterator;
20 import java.util.NoSuchElementException;
21
22 import org.joda.primitives.ShortUtils;
23 import org.joda.primitives.collection.ShortCollection;
24 import org.joda.primitives.iterator.ShortIterator;
25
26 /**
27 * Array based implementation of <code>ShortCollection</code> for
28 * primitive <code>short</code> elements.
29 * <p>
30 * This collection implementation allows multiple copies of the same value to be added.
31 * Internally, it uses an array, and behaves much like a list.
32 * <p>
33 * This class implements {@link java.util.Collection Collection} allowing
34 * seamless integration with other APIs.
35 * <p>
36 * Add, Remove and Clear are supported.
37 *
38 * @author Stephen Colebourne
39 * @author Jason Tiscione
40 * @version CODE GENERATED
41 * @since 1.0
42 */
43 public class ArrayShortCollection extends AbstractShortCollection implements Cloneable {
44 // This file is CODE GENERATED. Do not change manually.
45
46 /** The minimum size allowed when growth occurs */
47 private static final int MIN_GROWTH_SIZE = 4;
48 /** The amount the collection grows by when resized (3/2) */
49 private static final int GROWTH_FACTOR_MULTIPLIER = 3;
50 /** The amount the collection grows by when resized (3/2) */
51 private static final int GROWTH_FACTOR_DIVISOR = 2;
52
53 /** The array of elements */
54 private short[] data;
55 /** The current size */
56 private int size;
57
58 /**
59 * Constructor.
60 */
61 public ArrayShortCollection() {
62 super();
63 data = ShortUtils.EMPTY_SHORT_ARRAY;
64 }
65
66 /**
67 * Constructor that defines an initial size for the internal storage array.
68 *
69 * @param initialSize the initial size of the internal array, negative treated as zero
70 */
71 public ArrayShortCollection(int initialSize) {
72 super();
73 if (initialSize <= 0) {
74 data = ShortUtils.EMPTY_SHORT_ARRAY;
75 } else {
76 data = new short[initialSize];
77 }
78 }
79
80 /**
81 * Constructor that copies the specified values.
82 *
83 * @param values an array of values to copy, null treated as zero size array
84 */
85 public ArrayShortCollection(short[] values) {
86 super();
87 if (values == null) {
88 data = ShortUtils.EMPTY_SHORT_ARRAY;
89 } else {
90 data = (short[]) values.clone();
91 size = values.length;
92 }
93 }
94
95 /**
96 * Constructs a new collection by copying values from another collection.
97 *
98 * @param coll a collection of values to copy, null treated as zero size collection
99 */
100 public ArrayShortCollection(Collection<?> coll) {
101 super();
102 if (coll == null) {
103 data = ShortUtils.EMPTY_SHORT_ARRAY;
104 } else if (coll instanceof ShortCollection) {
105 ShortCollection c = (ShortCollection) coll;
106 size = c.size();
107 data = new short[size];
108 c.toShortArray(data, 0);
109 } else {
110 data = toPrimitiveArray(coll);
111 size = coll.size();
112 }
113 }
114
115 /**
116 * Constructs a new collection by copying values from an iterator.
117 *
118 * @param it an iterator of values to extract, null treated as zero size collection
119 */
120 public ArrayShortCollection(Iterator<Short> it) {
121 super();
122 if (it == null) {
123 data = ShortUtils.EMPTY_SHORT_ARRAY;
124 } else if (it instanceof ShortIterator) {
125 ShortIterator typed = (ShortIterator) it;
126 data = new short[MIN_GROWTH_SIZE];
127 while (typed.hasNext()) {
128 add(typed.nextShort());
129 }
130 } else {
131 data = new short[MIN_GROWTH_SIZE];
132 while (it.hasNext()) {
133 add(it.next());
134 }
135 }
136 }
137
138 // Implementation
139 //-----------------------------------------------------------------------
140 /**
141 * Gets the current size of the collection.
142 *
143 * @return the current size
144 */
145 public int size() {
146 return size;
147 }
148
149 /**
150 * Gets an iterator over this collection capable of accessing the primitive values.
151 *
152 * @return an iterator over this collection
153 */
154 public ShortIterator iterator() {
155 return new PIterator(this);
156 }
157
158 /**
159 * Adds a primitive value to this collection.
160 *
161 * @param value the value to add to this collection
162 * @return <code>true</code> if this collection was modified by this method call
163 * @throws IllegalArgumentException if value is rejected by this collection
164 */
165 public boolean add(short value) {
166 ensureCapacity(size + 1);
167 data[size++] = value;
168 return true;
169 }
170
171 // Overrides
172 //-----------------------------------------------------------------------
173 /**
174 * Optimizes the implementation.
175 * <p>
176 * This implementation changes the internal array to be the same size as
177 * the size of the collection.
178 */
179 public void optimize() {
180 if (size < data.length) {
181 short[] array = new short[size];
182 System.arraycopy(data, 0, array, 0, size);
183 data = array;
184 }
185 }
186
187 /**
188 * Are the add methods supported.
189 *
190 * @return <code>true</code>
191 */
192 protected boolean isAddModifiable() {
193 return true;
194 }
195
196 /**
197 * Are the remove methods supported.
198 *
199 * @return <code>true</code>
200 */
201 protected boolean isRemoveModifiable() {
202 return true;
203 }
204
205 /**
206 * Checks whether the object can currently be modified.
207 *
208 * @return <code>true</code>
209 */
210 public boolean isModifiable() {
211 return true;
212 }
213
214 /**
215 * Checks whether this collection contains a specified primitive value.
216 * <p>
217 * This implementation uses the internal array directly.
218 *
219 * @param value the value to search for
220 * @return <code>true</code> if the value is found
221 */
222 public boolean contains(short value) {
223 for (int i = 0; i < size; i++) {
224 if (data[i] == value) {
225 return true;
226 }
227 }
228 return false;
229 }
230
231 /**
232 * Clears the collection of all elements.
233 * The collection will have a zero size after this method completes.
234 * <p>
235 * This implementation resets the size, but does not reduce the internal storage array.
236 */
237 public void clear() {
238 size = 0;
239 }
240
241 /**
242 * Adds an array of primitive values to this collection.
243 *
244 * @param values the values to add to this collection
245 * @return <code>true</code> if this collection was modified by this method call
246 */
247 public boolean addAll(short[] values) {
248 checkAddModifiable();
249 if (values == null || values.length == 0) {
250 return false;
251 }
252 return doAdd(0, values);
253 }
254
255 /**
256 * Adds a collection of primitive values to this collection.
257 *
258 * @param values the values to add to this collection, null treated as empty collection
259 * @return <code>true</code> if this collection was modified by this method call
260 */
261 public boolean addAll(ShortCollection values) {
262 checkAddModifiable();
263 if (values == null || values.size() == 0) {
264 return false;
265 }
266 int len = values.size();
267 ensureCapacity(size + len);
268 values.toShortArray(data, size);
269 size += len;
270 return true;
271 }
272
273 /**
274 * Adds a range of primitive values to this collection.
275 * <p>
276 * The range is defined to be inclusive of the start and end.
277 * If the start is greater than the end then the range is equivalent to an empty collection.
278 *
279 * @param startInclusive the inclusive range start value
280 * @param endInclusive the inclusive range end value
281 * @return <code>true</code> if this collection was modified by this method call
282 * @throws IllegalArgumentException if a value is rejected by this set
283 * @throws UnsupportedOperationException if not supported by this set
284 */
285 public boolean addAll(short startInclusive, short endInclusive) {
286 int increase = endInclusive - startInclusive + 1;
287 if (increase < 0) {
288 return false;
289 }
290 ensureCapacity(size + increase);
291 short i = startInclusive;
292 while (i < endInclusive) {
293 data[size++] = i++;
294 }
295 data[size++] = i; // handles endInclusive=MAX_VALUE
296 return true;
297 }
298
299 /**
300 * Clone implementation that calls Object clone().
301 *
302 * @return the clone
303 */
304 public Object clone() {
305 ArrayShortCollection cloned = (ArrayShortCollection) super.clone();
306 cloned.data = (short[]) data.clone();
307 return cloned;
308 }
309
310 /**
311 * Copies data from this collection into the specified array.
312 * This method is pre-validated.
313 *
314 * @param fromIndex the index to start from
315 * @param dest the destination array
316 * @param destIndex the destination start index
317 * @param size the number of items to copy
318 */
319 protected void arrayCopy(int fromIndex, short[] dest, int destIndex, int size) {
320 System.arraycopy(data, fromIndex, dest, destIndex, size);
321 }
322
323 // Internal implementation
324 //-----------------------------------------------------------------------
325 /**
326 * Internal implementation to add to this collection at the specified index.
327 * This method adjusts the capacity and size.
328 *
329 * @param index the index to add at, valid
330 * @param values the array to add, not null
331 * @return true if the array was updated
332 */
333 protected boolean doAdd(int index, short[] values) {
334 int len = values.length;
335 ensureCapacity(size + len);
336 System.arraycopy(values, 0, data, size, len);
337 size += len;
338 return (len > 0);
339 }
340
341 /**
342 * Internal implementation to remove the element at the specified index.
343 *
344 * @param index the index, valid
345 */
346 protected void doRemoveIndex(int index) {
347 System.arraycopy(data, index + 1, data, index, size - 1 - index);
348 size--;
349 }
350
351 /**
352 * Internal implementation to ensure that the internal storage array has
353 * at least the specified size.
354 *
355 * @param reqCapacity the amount to expand to
356 */
357 protected void ensureCapacity(int reqCapacity) {
358 int curCapacity = data.length;
359 if (reqCapacity <= curCapacity) {
360 return;
361 }
362 int newCapacity = curCapacity * GROWTH_FACTOR_MULTIPLIER / GROWTH_FACTOR_DIVISOR;
363 if ((newCapacity - curCapacity) < MIN_GROWTH_SIZE) {
364 newCapacity = curCapacity + MIN_GROWTH_SIZE;
365 }
366 if (newCapacity < reqCapacity) {
367 newCapacity = reqCapacity;
368 }
369 short[] newArray = new short[newCapacity];
370 System.arraycopy(data, 0, newArray, 0, curCapacity);
371 data = newArray;
372 }
373
374 // Iterator
375 //-----------------------------------------------------------------------
376 /**
377 * Iterator.
378 */
379 protected static class PIterator implements ShortIterator {
380
381 private final ArrayShortCollection collection;
382 private int cursor = 0;
383 private boolean canRemove = false;
384
385 protected PIterator(ArrayShortCollection coll) {
386 super();
387 this.collection = coll;
388 }
389
390 public boolean hasNext() {
391 return (cursor < collection.size);
392 }
393
394 public short nextShort() {
395 if (hasNext() == false) {
396 throw new NoSuchElementException("No more elements available");
397 }
398 canRemove = true;
399 return collection.data[cursor++];
400 }
401
402 public Short next() {
403 return collection.toObject(nextShort());
404 }
405
406 public void remove() {
407 if (canRemove == false) {
408 throw new IllegalStateException("Element cannot be removed");
409 }
410 collection.doRemoveIndex(--cursor);
411 canRemove = false;
412 }
413
414 public boolean isModifiable() {
415 return collection.isModifiable();
416 }
417
418 public boolean isResettable() {
419 return true;
420 }
421
422 public void reset() {
423 cursor = 0;
424 }
425 }
426
427 }