View Javadoc

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 }