001/* 002 * Copyright 2001-2010 Stephen Colebourne 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.joda.primitives.collection.impl; 017 018import java.util.Collection; 019import java.util.Iterator; 020import java.util.NoSuchElementException; 021 022import org.joda.primitives.BooleanUtils; 023import org.joda.primitives.collection.BooleanCollection; 024import org.joda.primitives.iterator.BooleanIterator; 025 026/** 027 * Array based implementation of <code>BooleanCollection</code> for 028 * primitive <code>boolean</code> elements. 029 * <p> 030 * This collection implementation allows multiple copies of the same value to be added. 031 * Internally, it uses an array, and behaves much like a list. 032 * <p> 033 * This class implements {@link java.util.Collection Collection} allowing 034 * seamless integration with other APIs. 035 * <p> 036 * Add, Remove and Clear are supported. 037 * 038 * @author Stephen Colebourne 039 * @author Jason Tiscione 040 * @version CODE GENERATED 041 * @since 1.0 042 */ 043public class ArrayBooleanCollection extends AbstractBooleanCollection implements Cloneable { 044 // This file is CODE GENERATED. Do not change manually. 045 046 /** The minimum size allowed when growth occurs */ 047 private static final int MIN_GROWTH_SIZE = 4; 048 /** The amount the collection grows by when resized (3/2) */ 049 private static final int GROWTH_FACTOR_MULTIPLIER = 3; 050 /** The amount the collection grows by when resized (3/2) */ 051 private static final int GROWTH_FACTOR_DIVISOR = 2; 052 053 /** The array of elements */ 054 private boolean[] data; 055 /** The current size */ 056 private int size; 057 058 /** 059 * Constructor. 060 */ 061 public ArrayBooleanCollection() { 062 super(); 063 data = BooleanUtils.EMPTY_BOOLEAN_ARRAY; 064 } 065 066 /** 067 * Constructor that defines an initial size for the internal storage array. 068 * 069 * @param initialSize the initial size of the internal array, negative treated as zero 070 */ 071 public ArrayBooleanCollection(int initialSize) { 072 super(); 073 if (initialSize <= 0) { 074 data = BooleanUtils.EMPTY_BOOLEAN_ARRAY; 075 } else { 076 data = new boolean[initialSize]; 077 } 078 } 079 080 /** 081 * Constructor that copies the specified values. 082 * 083 * @param values an array of values to copy, null treated as zero size array 084 */ 085 public ArrayBooleanCollection(boolean[] values) { 086 super(); 087 if (values == null) { 088 data = BooleanUtils.EMPTY_BOOLEAN_ARRAY; 089 } else { 090 data = (boolean[]) values.clone(); 091 size = values.length; 092 } 093 } 094 095 /** 096 * Constructs a new collection by copying values from another collection. 097 * 098 * @param coll a collection of values to copy, null treated as zero size collection 099 */ 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}