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.util.Collection;
19  import java.util.Iterator;
20  import java.util.NoSuchElementException;
21  
22  import org.joda.primitives.BooleanUtils;
23  import org.joda.primitives.collection.BooleanCollection;
24  import org.joda.primitives.iterator.BooleanIterator;
25  
26  /**
27   * Array based implementation of <code>BooleanCollection</code> for
28   * primitive <code>boolean</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 ArrayBooleanCollection extends AbstractBooleanCollection 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 boolean[] data;
55      /** The current size */
56      private int size;
57  
58      /**
59       * Constructor.
60       */
61      public ArrayBooleanCollection() {
62          super();
63          data = BooleanUtils.EMPTY_BOOLEAN_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 ArrayBooleanCollection(int initialSize) {
72          super();
73          if (initialSize <= 0) {
74              data = BooleanUtils.EMPTY_BOOLEAN_ARRAY;
75          } else {
76              data = new boolean[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 ArrayBooleanCollection(boolean[] values) {
86          super();
87          if (values == null) {
88              data = BooleanUtils.EMPTY_BOOLEAN_ARRAY;
89          } else {
90              data = (boolean[]) 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 ArrayBooleanCollection(Collection<?> coll) {
101         super();
102         if (coll == null) {
103             data = BooleanUtils.EMPTY_BOOLEAN_ARRAY;
104         } else if (coll instanceof BooleanCollection) {
105             BooleanCollection c = (BooleanCollection) coll;
106             size = c.size();
107             data = new boolean[size];
108             c.toBooleanArray(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 ArrayBooleanCollection(Iterator<Boolean> it) {
121         super();
122         if (it == null) {
123             data = BooleanUtils.EMPTY_BOOLEAN_ARRAY;
124         } else if (it instanceof BooleanIterator) {
125             BooleanIterator typed = (BooleanIterator) it;
126             data = new boolean[MIN_GROWTH_SIZE];
127             while (typed.hasNext()) {
128                 add(typed.nextBoolean());
129             }
130         } else {
131             data = new boolean[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 BooleanIterator 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(boolean 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             boolean[] array = new boolean[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(boolean 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(boolean[] 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(BooleanCollection 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.toBooleanArray(data, size);
269         size += len;
270         return true;
271     }
272 
273     /**
274      * Clone implementation that calls Object clone().
275      *
276      * @return the clone
277      */
278     public Object clone() {
279         ArrayBooleanCollection cloned = (ArrayBooleanCollection) super.clone();
280         cloned.data = (boolean[]) data.clone();
281         return cloned;
282     }
283 
284     /**
285      * Copies data from this collection into the specified array.
286      * This method is pre-validated.
287      *
288      * @param fromIndex  the index to start from
289      * @param dest  the destination array
290      * @param destIndex  the destination start index
291      * @param size  the number of items to copy
292      */
293     protected void arrayCopy(int fromIndex, boolean[] dest, int destIndex, int size) {
294         System.arraycopy(data, fromIndex, dest, destIndex, size);
295     }
296 
297     // Internal implementation
298     //-----------------------------------------------------------------------
299     /**
300      * Internal implementation to add to this collection at the specified index.
301      * This method adjusts the capacity and size.
302      * 
303      * @param index  the index to add at, valid
304      * @param values  the array to add, not null
305      * @return true if the array was updated
306      */
307     protected boolean doAdd(int index, boolean[] 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      * Internal implementation to remove the element at the specified index.
317      * 
318      * @param index  the index, valid
319      */
320     protected void doRemoveIndex(int index) {
321         System.arraycopy(data, index + 1, data, index, size - 1 - index);
322         size--;
323     }
324 
325     /**
326      * Internal implementation to ensure that the internal storage array has
327      * at least the specified size.
328      * 
329      * @param reqCapacity  the amount to expand to
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         boolean[] newArray = new boolean[newCapacity];
344         System.arraycopy(data, 0, newArray, 0, curCapacity);
345         data = newArray;
346     }
347 
348     // Iterator
349     //-----------------------------------------------------------------------
350     /**
351      * Iterator.
352      */
353     protected static class PIterator implements BooleanIterator {
354 
355         private final ArrayBooleanCollection collection;
356         private int cursor = 0;
357         private boolean canRemove = false;
358 
359         protected PIterator(ArrayBooleanCollection coll) {
360             super();
361             this.collection = coll;
362         }
363 
364         public boolean hasNext() {
365             return (cursor < collection.size);
366         }
367 
368         public boolean nextBoolean() {
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 Boolean next() {
377             return collection.toObject(nextBoolean());
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 }