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.lang.reflect.Array;
19 import java.util.Collection;
20 import java.util.Iterator;
21
22 import org.joda.primitives.DoubleUtils;
23 import org.joda.primitives.collection.DoubleCollection;
24 import org.joda.primitives.iterator.DoubleIterator;
25
26 /**
27 * Abstract base class for collections of primitive <code>double</code> elements.
28 * <p>
29 * This class implements {@link java.util.Collection Collection} allowing
30 * seamless integration with other APIs.
31 * <p>
32 * The <code>iterator</code> and <code>size</code> must be implemented by subclases.
33 * To make the subclass modifiable, the <code>add(double)</code> and
34 * iterator <code>remove()</code> methods must also be implemented.
35 * Subclasses may override other methods to increase efficiency.
36 *
37 * @author Stephen Colebourne
38 * @author Jason Tiscione
39 * @version CODE GENERATED
40 * @since 1.0
41 */
42 public abstract class AbstractDoubleCollection
43 extends AbstractPrimitiveCollectable<Double>
44 implements DoubleCollection {
45 // This file is CODE GENERATED. Do not change manually.
46
47 /**
48 * Constructor.
49 */
50 protected AbstractDoubleCollection() {
51 super();
52 }
53
54 // Mandatory operations
55 //-----------------------------------------------------------------------
56 /**
57 * Checks whether this collection contains a specified primitive value.
58 * <p>
59 * This implementation uses <code>doubleIterator()</code>.
60 *
61 * @param value the value to search for
62 * @return <code>true</code> if the value is found
63 */
64 public boolean contains(double value) {
65 for (DoubleIterator it = iterator(); it.hasNext();) {
66 if (it.nextDouble() == value) {
67 return true;
68 }
69 }
70 return false;
71 }
72
73 /**
74 * Checks if this collection contains all of the values in the specified array.
75 * If the specified array is empty, <code>true</code> is returned.
76 * <p>
77 * This implementation uses <code>contains(double)</code>.
78 *
79 * @param values the values to search for, null treated as empty array
80 * @return <code>true</code> if all of the values are found
81 */
82 public boolean containsAll(double[] values) {
83 if (values != null) {
84 for (int i = 0; i < values.length; i++) {
85 if (contains(values[i]) == false) {
86 return false;
87 }
88 }
89 }
90 return true;
91 }
92
93 /**
94 * Checks if this collection contains all of the values in the specified collection.
95 * If the specified collection is empty, <code>true</code> is returned.
96 * <p>
97 * This implementation uses <code>contains(double)</code>.
98 *
99 * @param values the values to search for, null treated as empty collection
100 * @return <code>true</code> if all of the values are found
101 */
102 public boolean containsAll(DoubleCollection values) {
103 if (values != null) {
104 for (DoubleIterator it = values.iterator(); it.hasNext(); ) {
105 if (contains(it.nextDouble()) == false) {
106 return false;
107 }
108 }
109 }
110 return true;
111 }
112
113 /**
114 * Checks if this collection contains any of the values in the specified array.
115 * If the specified array is empty, <code>false</code> is returned.
116 * <p>
117 * This implementation uses <code>contains(double)</code>.
118 *
119 * @param values the values to search for, null treated as empty array
120 * @return <code>true</code> if at least one of the values is found
121 */
122 public boolean containsAny(double[] values) {
123 if (values != null) {
124 for (int i = 0; i < values.length; i++) {
125 if (contains(values[i])) {
126 return true;
127 }
128 }
129 }
130 return false;
131 }
132
133 /**
134 * Checks if this collection contains any of the values in the specified collection.
135 * If the specified collection is empty, <code>false</code> is returned.
136 * <p>
137 * This implementation uses <code>contains(double)</code>.
138 *
139 * @param values the values to search for, null treated as empty collection
140 * @return <code>true</code> if at least one of the values is found
141 */
142 public boolean containsAny(DoubleCollection values) {
143 if (values != null) {
144 for (DoubleIterator it = values.iterator(); it.hasNext(); ) {
145 if (contains(it.nextDouble())) {
146 return true;
147 }
148 }
149 }
150 return false;
151 }
152
153 /**
154 * Gets the elements of this collection as an array.
155 * <p>
156 * This implementation uses <code>arrayCopy</code>.
157 *
158 * @return a new array containing a copy of the elements of this collection
159 */
160 public double[] toDoubleArray() {
161 if (size() == 0) {
162 return DoubleUtils.EMPTY_DOUBLE_ARRAY;
163 }
164 double[] result = new double[size()];
165 arrayCopy(0, result, 0, size());
166 return result;
167 }
168
169 /**
170 * Copies the elements of this collection into an array at a specified position.
171 * Previous values in the array are overwritten.
172 * <p>
173 * If the array specified is null a new array is created.
174 * If the array specified is large enough, it will be modified.
175 * If the array is not large enough, a new array will be created containing the
176 * values from the specified array before the startIndex plus those from this collection.
177 * <p>
178 * This implementation uses <code>arrayCopy</code>.
179 *
180 * @param array the array to add the elements to, null treated as empty array
181 * @param startIndex the position in the array to start setting elements
182 * @return the array with the populated collection
183 * @throws IndexOutOfBoundsException if the index is negative
184 */
185 public double[] toDoubleArray(double[] array, int startIndex) {
186 if (startIndex < 0) {
187 throw new IndexOutOfBoundsException("Start index must not be negative: " + startIndex);
188 }
189 double[] result = null;
190 if (array == null) {
191 // create new
192 result = new double[startIndex + size()];
193
194 } else if (array.length - startIndex - size() >= 0) {
195 // room to fit data
196 result = array;
197
198 } else {
199 // expand array
200 result = new double[startIndex + size()];
201 System.arraycopy(array, 0, result, 0, startIndex);
202 }
203 arrayCopy(0, result, startIndex, size());
204 return result;
205 }
206
207 // Optional operations
208 //-----------------------------------------------------------------------
209 /**
210 * Clears the collection/map of all elements (optional operation).
211 * <p>
212 * The collection/map will have a zero size after this method completes.
213 * This method is optional, throwing an UnsupportedOperationException if the
214 * collection/map cannot be cleared.
215 * <p>
216 * This implementation uses <code>iterator()</code>.
217 *
218 * @throws UnsupportedOperationException if method not supported by this collection
219 */
220 public void clear() {
221 checkRemoveModifiable();
222 for (DoubleIterator it = iterator(); it.hasNext();) {
223 it.nextDouble();
224 it.remove();
225 }
226 }
227
228 /**
229 * Adds a primitive value to this collection (optional operation).
230 * <p>
231 * This implementation throws UnsupportedOperationException.
232 *
233 * @param value the value to add to this collection
234 * @return <code>true</code> if this collection was modified by this method call
235 * @throws IllegalArgumentException if value is rejected by this collection
236 * @throws UnsupportedOperationException if not supported by this collection
237 */
238 public boolean add(double value) {
239 throw new UnsupportedOperationException("Collection does not support add");
240 }
241
242 /**
243 * Adds an array of primitive values to this collection (optional operation).
244 * <p>
245 * This implementation uses <code>add(double)</code>.
246 *
247 * @param values the values to add to this collection, null treated as empty array
248 * @return <code>true</code> if this collection was modified by this method call
249 * @throws IllegalArgumentException if a value is rejected by this collection
250 * @throws UnsupportedOperationException if not supported by this collection
251 */
252 public boolean addAll(double[] values) {
253 checkAddModifiable();
254 boolean changed = false;
255 if (values != null) {
256 for (int i = 0; i < values.length; i++) {
257 changed |= add(values[i]);
258 }
259 }
260 return changed;
261 }
262
263 /**
264 * Adds a collection of primitive values to this collection (optional operation).
265 * <p>
266 * This implementation uses <code>add(double)</code>.
267 *
268 * @param values the values to add to this collection, null treated as empty collection
269 * @return <code>true</code> if this collection was modified by this method call
270 * @throws IllegalArgumentException if a value is rejected by this collection
271 * @throws UnsupportedOperationException if not supported by this collection
272 */
273 public boolean addAll(DoubleCollection values) {
274 checkAddModifiable();
275 boolean changed = false;
276 if (values != null) {
277 for (DoubleIterator it = values.iterator(); it.hasNext(); ) {
278 changed |= add(it.nextDouble());
279 }
280 }
281 return changed;
282 }
283
284 /**
285 * Removes the first occurrence of the specified primitive value from this collection
286 * <p>
287 * This implementation uses <code>iterator().remove()</code>.
288 *
289 * @param value the value to remove
290 * @return <code>true</code> if this collection was modified by this method call
291 * @throws UnsupportedOperationException if not supported by this collection
292 */
293 public boolean removeFirst(double value) {
294 checkRemoveModifiable();
295 for (DoubleIterator it = iterator(); it.hasNext(); ) {
296 if (it.nextDouble() == value) {
297 it.remove();
298 return true;
299 }
300 }
301 return false;
302 }
303
304 /**
305 * Removes all occurrences of the specified primitive value from this collection.
306 * <p>
307 * This implementation uses <code>iterator().remove()</code>.
308 *
309 * @param value the value to remove
310 * @return <code>true</code> if this collection was modified by this method call
311 * @throws UnsupportedOperationException if not supported by this collection
312 */
313 public boolean removeAll(double value) {
314 checkRemoveModifiable();
315 boolean changed = false;
316 for (DoubleIterator it = iterator(); it.hasNext(); ) {
317 if (it.nextDouble() == value) {
318 it.remove();
319 changed = true;
320 }
321 }
322 return changed;
323 }
324
325 /**
326 * Removes all occurrences from this collection of each primitive in the specified array.
327 * <p>
328 * This implementation uses <code>iterator().remove()</code>.
329 *
330 * @param values the values to remove from this collection, null treated as empty array
331 * @return <code>true</code> if this list was modified by this method call
332 * @throws UnsupportedOperationException if not supported by this collection
333 */
334 public boolean removeAll(double[] values) {
335 checkRemoveModifiable();
336 boolean changed = false;
337 if (values != null) {
338 for (DoubleIterator it = iterator(); it.hasNext(); ) {
339 double value = it.nextDouble();
340 for (int i = 0; i < values.length; i++) {
341 if (values[i] == value) {
342 it.remove();
343 changed = true;
344 }
345 }
346 }
347 }
348 return changed;
349 }
350
351 /**
352 * Removes all occurrences from this collection of each primitive in the specified collection.
353 * <p>
354 * This implementation uses <code>iterator().remove()</code>.
355 *
356 * @param values the values to remove from this collection, null treated as empty collection
357 * @return <code>true</code> if this list was modified by this method call
358 * @throws UnsupportedOperationException if not supported by this collection
359 */
360 public boolean removeAll(DoubleCollection values) {
361 checkRemoveModifiable();
362 boolean changed = false;
363 if (values != null) {
364 for (DoubleIterator it = iterator(); it.hasNext(); ) {
365 if (values.contains(it.nextDouble())) {
366 it.remove();
367 changed = true;
368 }
369 }
370 }
371 return changed;
372 }
373
374 /**
375 * Retains each element of this collection that is present in the specified array
376 * removing all other values.
377 * <p>
378 * This implementation uses <code>iterator().remove()</code>.
379 *
380 * @param values the values to remove from this collection, null treated as empty array
381 * @return <code>true</code> if this list was modified by this method call
382 * @throws UnsupportedOperationException if not supported by this collection
383 */
384 public boolean retainAll(double[] values) {
385 checkRemoveModifiable();
386 boolean changed = false;
387 if (values == null || values.length == 0) {
388 changed = !isEmpty();
389 clear();
390 } else {
391 for (DoubleIterator it = iterator(); it.hasNext(); ) {
392 double next = it.nextDouble();
393 boolean match = false;
394 for (int i = 0; i < values.length; i++) {
395 if (values[i] == next) {
396 match = true;
397 break;
398 }
399 }
400 if (match == false) {
401 it.remove();
402 changed = true;
403 }
404 }
405 }
406 return changed;
407 }
408
409 /**
410 * Retains each element of this collection that is present in the specified collection
411 * removing all other values.
412 * <p>
413 * This implementation uses <code>iterator().remove()</code>.
414 *
415 * @param values the values to retain in this collection, null treated as empty collection
416 * @return <code>true</code> if this collection was modified by this method call
417 * @throws UnsupportedOperationException if not supported by this collection
418 */
419 public boolean retainAll(DoubleCollection values) {
420 checkRemoveModifiable();
421 boolean changed = false;
422 if (values == null || values.isEmpty()) {
423 changed = !isEmpty();
424 clear();
425 } else {
426 for (DoubleIterator it = iterator(); it.hasNext(); ) {
427 if (values.contains(it.nextDouble()) == false) {
428 it.remove();
429 changed = true;
430 }
431 }
432 }
433 return changed;
434 }
435
436 // Collection integration
437 //-----------------------------------------------------------------------
438 /**
439 * Checks whether this collection contains a specified <code>Double</code> value.
440 * <p>
441 * This implementation uses <code>contains(double)</code>.
442 *
443 * @param value the value to search for
444 * @return <code>true</code> if the value is found
445 */
446 public boolean contains(Object value) {
447 return contains(toPrimitive(value));
448 }
449
450 /**
451 * Checks if the collection contains all of the primitive values.
452 * <p>
453 * This implementation uses <code>containsAll(double[])</code>.
454 *
455 * @param coll the collection of values to search for
456 * @return <code>true</code> if all the values are found
457 */
458 public boolean containsAll(Collection<?> coll) {
459 if (coll == this || coll.size() == 0) {
460 return true;
461 }
462 if (size() == 0) {
463 return false;
464 }
465 return containsAll(toPrimitiveArray(coll));
466 }
467
468 /**
469 * Checks if the collection contains any of the primitive values in the array.
470 * If the specified collection is empty, <code>false</code> is returned.
471 * <p>
472 * This implementation uses <code>containsAny(double[])</code>.
473 *
474 * @param coll the collection of values to search for
475 * @return <code>true</code> if at least one of the values is found
476 */
477 public boolean containsAny(Collection<?> coll) {
478 if (size() == 0 || coll.size() == 0) {
479 return false;
480 }
481 if (coll == this) {
482 return true;
483 }
484 return containsAny(toPrimitiveArray(coll));
485 }
486
487 /**
488 * Gets the collection as an array of <code>Double</code>.
489 *
490 * @return an array of <code>Double</code>
491 */
492 public Object[] toArray() {
493 Object[] result = new Double[size()];
494 DoubleIterator it = iterator();
495 for (int i = 0; it.hasNext(); i++) {
496 result[i] = it.next();
497 }
498 return result;
499 }
500
501 /**
502 * Gets the collection as an array, using the array provided.
503 *
504 * @param array the array to populate
505 * @return an array of <code>Double</code>
506 */
507 @SuppressWarnings("unchecked")
508 public <T> T[] toArray(T[] array) {
509 int size = size();
510 if (array.length < size) {
511 array = (T[]) Array.newInstance(array.getClass().getComponentType(), size);
512 }
513
514 Iterator<Double> it = iterator();
515 for (int i = 0; i < size; i++) {
516 array[i] = (T)it.next();
517 }
518
519 if (array.length > size) {
520 array[size] = null;
521 }
522
523 return array;
524 }
525
526 /**
527 * Adds the <code>Double</code> value to this collection (optional operation).
528 * <p>
529 * This method is optional, throwing an UnsupportedOperationException if the
530 * collection cannot be added to.
531 * <p>
532 * This implementation uses <code>add(double)</code>.
533 *
534 * @param value the value to add to this collection
535 * @return <code>true</code> if this collection was modified by this method call
536 * @throws IllegalArgumentException if value is rejected by this collection
537 * @throws UnsupportedOperationException if not supported by this collection
538 */
539 public boolean add(Double value) {
540 checkAddModifiable();
541 return add(toPrimitive(value));
542 }
543
544 /**
545 * Adds a collection of <code>Double</code> values to this collection (optional operation).
546 * <p>
547 * This method is optional, throwing an UnsupportedOperationException if the
548 * collection cannot be added to.
549 * <p>
550 * This implementation uses <code>addAll(double[])</code>.
551 *
552 * @param coll the values to add to this collection
553 * @return <code>true</code> if this list was modified by this method call
554 * @throws IndexOutOfBoundsException if the index is invalid
555 * @throws ClassCastException if any object is not <code>Double</code>
556 * @throws IllegalArgumentException if value is rejected by this collection
557 * @throws UnsupportedOperationException if not supported by this collection
558 */
559 public boolean addAll(Collection<? extends Double> coll) {
560 checkAddModifiable();
561 return addAll(toPrimitiveArray(coll));
562 }
563
564 /**
565 * Removes the first occurrance of the specified <code>Double</code> value from
566 * this collection (optional operation).
567 * <p>
568 * This method is optional, throwing an UnsupportedOperationException if the
569 * collection cannot be removed from.
570 * <p>
571 * This implementation uses <code>removeFirst(double)</code>.
572 *
573 * @param value the value to remove
574 * @return <code>true</code> if this collection was modified by this method call
575 * @throws UnsupportedOperationException if not supported by this collection
576 */
577 public boolean remove(Object value) {
578 checkRemoveModifiable();
579 return removeFirst(toPrimitive(value));
580 }
581
582 /**
583 * Removes each of a collection of <code>Double</code> values from this collection (optional operation).
584 * <p>
585 * This method is optional, throwing an UnsupportedOperationException if the
586 * collection cannot be added to.
587 * <p>
588 * This implementation uses <code>removeAll(double[])</code>.
589 *
590 * @param coll the values to remove from this collection
591 * @return <code>true</code> if this list was modified by this method call
592 * @throws UnsupportedOperationException if not supported by this collection
593 */
594 public boolean removeAll(Collection<?> coll) {
595 checkRemoveModifiable();
596 if (coll == this) {
597 int size = size();
598 clear();
599 return (size() != size);
600 }
601 return removeAll(toPrimitiveArray(coll));
602 }
603
604 /**
605 * Retains each of a collection of <code>Double</code> values, removing other
606 * values (optional operation).
607 * <p>
608 * This method is optional, throwing an UnsupportedOperationException if the
609 * collection cannot be added to.
610 * <p>
611 * This implementation uses <code>retainAll(double[])</code>.
612 *
613 * @param coll the values to retain in this collection
614 * @return <code>true</code> if this list was modified by this method call
615 * @throws UnsupportedOperationException if not supported by this collection
616 */
617 public boolean retainAll(Collection<?> coll) {
618 checkRemoveModifiable();
619 if (coll == this) {
620 return false;
621 }
622 return retainAll(toPrimitiveArray(coll));
623 }
624
625 // Basics
626 //-----------------------------------------------------------------------
627 /**
628 * Gets a string representing this collection.
629 * <p>
630 * The format used is as per <code>Collection</code>.
631 *
632 * @return collection as a String
633 */
634 public String toString() {
635 StringBuffer buf = new StringBuffer();
636 buf.append("[");
637
638 DoubleIterator it = iterator();
639 boolean hasNext = it.hasNext();
640 while (hasNext) {
641 buf.append(it.nextDouble());
642 hasNext = it.hasNext();
643 if (hasNext) {
644 buf.append(", ");
645 }
646 }
647
648 buf.append("]");
649 return buf.toString();
650 }
651
652 // Internals
653 //-----------------------------------------------------------------------
654 /**
655 * Copies data from this collection into the specified array.
656 * This method is pre-validated.
657 *
658 * @param fromIndex the index to start from
659 * @param dest the destination array
660 * @param destIndex the destination start index
661 * @param size the number of items to copy
662 */
663 protected void arrayCopy(int fromIndex, double[] dest, int destIndex, int size) {
664 DoubleIterator it = iterator();
665 for (int i = 0; it.hasNext() && i < size; i++) {
666 dest[destIndex + i] = it.nextDouble();
667 }
668 }
669
670 /**
671 * Are the add methods supported.
672 * <p>
673 * This implementation returns false.
674 *
675 * @return true if supported
676 */
677 protected boolean isAddModifiable() {
678 return false;
679 }
680
681 /**
682 * Are the remove methods supported.
683 * <p>
684 * This implementation returns false.
685 *
686 * @return true if supported
687 */
688 protected boolean isRemoveModifiable() {
689 return false;
690 }
691
692 /**
693 * Is the collection modifiable in any way.
694 *
695 * @return true if supported
696 */
697 public boolean isModifiable() {
698 return isAddModifiable() || isRemoveModifiable();
699 }
700
701 /**
702 * Check whether add is suported and throw an exception.
703 */
704 protected void checkAddModifiable() {
705 if (isAddModifiable() == false) {
706 throw new UnsupportedOperationException("Collection does not support add");
707 }
708 }
709
710 /**
711 * Check whether remove is suported and throw an exception.
712 */
713 protected void checkRemoveModifiable() {
714 if (isRemoveModifiable() == false) {
715 throw new UnsupportedOperationException("Collection does not support remove");
716 }
717 }
718
719 /**
720 * Wraps an <code>double</code> with an Object wrapper.
721 *
722 * @param value the primitive value
723 * @return the Object wrapper
724 */
725 protected Double toObject(double value) {
726 return DoubleUtils.toObject(value);
727 }
728
729 /**
730 * Checks if the object can be converted to a primitive successfully.
731 * <p>
732 * This implementation only allows non-null Double objects.
733 *
734 * @param value the Object wrapper
735 * @return true if a primitive value can be successfully extracted
736 */
737 protected boolean isToPrimitivePossible(Object value) {
738 return (value instanceof Double);
739 }
740
741 /**
742 * Unwraps the <code>Double</code> to retrieve the primitive <code>double</code>.
743 * <p>
744 * This implementation only allows non-null Double objects.
745 *
746 * @param value the Object to convert to a primitive
747 * @return the primitive value
748 * @throws NullPointerException if the value is null and this is unacceptable
749 * @throws ClassCastException if the object is of an unsuitable type
750 */
751 protected double toPrimitive(Object value) {
752 return DoubleUtils.toPrimitive(value);
753 }
754
755 /**
756 * Unwraps a <code>Collection</code> to retrieve the primitive <code>double</code>.
757 * <p>
758 * This implementation only allows non-null Double objects.
759 *
760 * @param coll the Collection to convert to primitives
761 * @return the primitive value
762 * @throws NullPointerException if the value is null and this is unacceptable
763 * @throws ClassCastException if any object is of an unsuitable type
764 */
765 protected double[] toPrimitiveArray(Collection<?> coll) {
766 return DoubleUtils.toPrimitiveArray(coll);
767 }
768
769 }