1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.DoubleUtils;
23 import org.joda.primitives.collection.DoubleCollection;
24 import org.joda.primitives.iterator.DoubleIterator;
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 public class ArrayDoubleCollection extends AbstractDoubleCollection implements Cloneable {
44
45
46
47 private static final int MIN_GROWTH_SIZE = 4;
48
49 private static final int GROWTH_FACTOR_MULTIPLIER = 3;
50
51 private static final int GROWTH_FACTOR_DIVISOR = 2;
52
53
54 private double[] data;
55
56 private int size;
57
58
59
60
61 public ArrayDoubleCollection() {
62 super();
63 data = DoubleUtils.EMPTY_DOUBLE_ARRAY;
64 }
65
66
67
68
69
70
71 public ArrayDoubleCollection(int initialSize) {
72 super();
73 if (initialSize <= 0) {
74 data = DoubleUtils.EMPTY_DOUBLE_ARRAY;
75 } else {
76 data = new double[initialSize];
77 }
78 }
79
80
81
82
83
84
85 public ArrayDoubleCollection(double[] values) {
86 super();
87 if (values == null) {
88 data = DoubleUtils.EMPTY_DOUBLE_ARRAY;
89 } else {
90 data = (double[]) values.clone();
91 size = values.length;
92 }
93 }
94
95
96
97
98
99
100 public ArrayDoubleCollection(Collection<?> coll) {
101 super();
102 if (coll == null) {
103 data = DoubleUtils.EMPTY_DOUBLE_ARRAY;
104 } else if (coll instanceof DoubleCollection) {
105 DoubleCollection c = (DoubleCollection) coll;
106 size = c.size();
107 data = new double[size];
108 c.toDoubleArray(data, 0);
109 } else {
110 data = toPrimitiveArray(coll);
111 size = coll.size();
112 }
113 }
114
115
116
117
118
119
120 public ArrayDoubleCollection(Iterator<Double> it) {
121 super();
122 if (it == null) {
123 data = DoubleUtils.EMPTY_DOUBLE_ARRAY;
124 } else if (it instanceof DoubleIterator) {
125 DoubleIterator typed = (DoubleIterator) it;
126 data = new double[MIN_GROWTH_SIZE];
127 while (typed.hasNext()) {
128 add(typed.nextDouble());
129 }
130 } else {
131 data = new double[MIN_GROWTH_SIZE];
132 while (it.hasNext()) {
133 add(it.next());
134 }
135 }
136 }
137
138
139
140
141
142
143
144
145 public int size() {
146 return size;
147 }
148
149
150
151
152
153
154 public DoubleIterator iterator() {
155 return new PIterator(this);
156 }
157
158
159
160
161
162
163
164
165 public boolean add(double value) {
166 ensureCapacity(size + 1);
167 data[size++] = value;
168 return true;
169 }
170
171
172
173
174
175
176
177
178
179 public void optimize() {
180 if (size < data.length) {
181 double[] array = new double[size];
182 System.arraycopy(data, 0, array, 0, size);
183 data = array;
184 }
185 }
186
187
188
189
190
191
192 protected boolean isAddModifiable() {
193 return true;
194 }
195
196
197
198
199
200
201 protected boolean isRemoveModifiable() {
202 return true;
203 }
204
205
206
207
208
209
210 public boolean isModifiable() {
211 return true;
212 }
213
214
215
216
217
218
219
220
221
222 public boolean contains(double 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
233
234
235
236
237 public void clear() {
238 size = 0;
239 }
240
241
242
243
244
245
246
247 public boolean addAll(double[] values) {
248 checkAddModifiable();
249 if (values == null || values.length == 0) {
250 return false;
251 }
252 return doAdd(0, values);
253 }
254
255
256
257
258
259
260
261 public boolean addAll(DoubleCollection 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.toDoubleArray(data, size);
269 size += len;
270 return true;
271 }
272
273
274
275
276
277
278 public Object clone() {
279 ArrayDoubleCollection cloned = (ArrayDoubleCollection) super.clone();
280 cloned.data = (double[]) data.clone();
281 return cloned;
282 }
283
284
285
286
287
288
289
290
291
292
293 protected void arrayCopy(int fromIndex, double[] dest, int destIndex, int size) {
294 System.arraycopy(data, fromIndex, dest, destIndex, size);
295 }
296
297
298
299
300
301
302
303
304
305
306
307 protected boolean doAdd(int index, double[] values) {
308 int len = values.length;
309 ensureCapacity(size + len);
310 System.arraycopy(values, 0, data, size, len);
311 size += len;
312 return (len > 0);
313 }
314
315
316
317
318
319
320 protected void doRemoveIndex(int index) {
321 System.arraycopy(data, index + 1, data, index, size - 1 - index);
322 size--;
323 }
324
325
326
327
328
329
330
331 protected void ensureCapacity(int reqCapacity) {
332 int curCapacity = data.length;
333 if (reqCapacity <= curCapacity) {
334 return;
335 }
336 int newCapacity = curCapacity * GROWTH_FACTOR_MULTIPLIER / GROWTH_FACTOR_DIVISOR;
337 if ((newCapacity - curCapacity) < MIN_GROWTH_SIZE) {
338 newCapacity = curCapacity + MIN_GROWTH_SIZE;
339 }
340 if (newCapacity < reqCapacity) {
341 newCapacity = reqCapacity;
342 }
343 double[] newArray = new double[newCapacity];
344 System.arraycopy(data, 0, newArray, 0, curCapacity);
345 data = newArray;
346 }
347
348
349
350
351
352
353 protected static class PIterator implements DoubleIterator {
354
355 private final ArrayDoubleCollection collection;
356 private int cursor = 0;
357 private boolean canRemove = false;
358
359 protected PIterator(ArrayDoubleCollection coll) {
360 super();
361 this.collection = coll;
362 }
363
364 public boolean hasNext() {
365 return (cursor < collection.size);
366 }
367
368 public double nextDouble() {
369 if (hasNext() == false) {
370 throw new NoSuchElementException("No more elements available");
371 }
372 canRemove = true;
373 return collection.data[cursor++];
374 }
375
376 public Double next() {
377 return collection.toObject(nextDouble());
378 }
379
380 public void remove() {
381 if (canRemove == false) {
382 throw new IllegalStateException("Element cannot be removed");
383 }
384 collection.doRemoveIndex(--cursor);
385 canRemove = false;
386 }
387
388 public boolean isModifiable() {
389 return collection.isModifiable();
390 }
391
392 public boolean isResettable() {
393 return true;
394 }
395
396 public void reset() {
397 cursor = 0;
398 }
399 }
400
401 }