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 */
016 package org.joda.primitives.list.impl;
017
018 import java.util.Collection;
019
020 import org.joda.primitives.CharUtils;
021
022 /**
023 * Array based implementation of <code>CharList</code> for
024 * primitive <code>int</code> elements.
025 * <p>
026 * This class implements {@link java.util.List List} allowing
027 * seamless integration with other APIs.
028 * <p>
029 * Add, Remove, Set and Clear are supported.
030 *
031 * @author Stephen Colebourne
032 * @author Rodney Waldhoff
033 * @author Jason Tiscione
034 * @version CODE GENERATED
035 * @since 1.0
036 */
037 public class ArrayCharList extends AbstractCharList implements Cloneable {
038 // This file is CODE GENERATED. Do not change manually.
039
040 /** The minimum size allowed when growth occurs */
041 private static final int MIN_GROWTH_SIZE = 4;
042 /** The amount the collection grows by when resized (3/2) */
043 private static final int GROWTH_FACTOR_MULTIPLIER = 3;
044 /** The amount the collection grows by when resized (3/2) */
045 private static final int GROWTH_FACTOR_DIVISOR = 2;
046
047 /** The array of elements */
048 private char[] data;
049 /** The current size */
050 private int size;
051
052 /**
053 * Constructor.
054 */
055 public ArrayCharList() {
056 super();
057 data = CharUtils.EMPTY_CHAR_ARRAY;
058 }
059
060 /**
061 * Constructor that defines an initial size for the internal storage array.
062 *
063 * @param initialSize the initial size of the internal array, negative treated as zero
064 */
065 public ArrayCharList(int initialSize) {
066 super();
067 if (initialSize <= 0) {
068 data = CharUtils.EMPTY_CHAR_ARRAY;
069 } else {
070 data = new char[initialSize];
071 }
072 }
073
074 /**
075 * Constructor that copies the specified values.
076 *
077 * @param values an array of values to copy, null treated as zero size array
078 */
079 public ArrayCharList(char[] values) {
080 super();
081 if (values == null) {
082 data = CharUtils.EMPTY_CHAR_ARRAY;
083 } else {
084 data = (char[]) values.clone();
085 size = values.length;
086 }
087 }
088
089 /**
090 * Constructor that copies the specified values.
091 *
092 * @param coll a collection of values to copy, null treated as zero size collection
093 */
094 public ArrayCharList(Collection<Character> coll) {
095 super();
096 if (coll == null) {
097 data = CharUtils.EMPTY_CHAR_ARRAY;
098 } else if (coll instanceof ArrayCharList) {
099 ArrayCharList c = (ArrayCharList) coll;
100 this.data = new char[c.size];
101 System.arraycopy(c.data, 0, this.data, 0, c.size);
102 size = c.size;
103 } else {
104 data = toPrimitiveArray(coll);
105 size = coll.size();
106 }
107 }
108
109 // Implementation
110 //-----------------------------------------------------------------------
111 /**
112 * Gets the current size of the collection.
113 *
114 * @return the current size
115 */
116 public int size() {
117 return size;
118 }
119
120 /**
121 * Gets the primitive value at the specified index.
122 *
123 * @param index the index to get from
124 * @return value at the index
125 * @throws IndexOutOfBoundsException if the index is invalid
126 */
127 public char getChar(int index) {
128 checkIndexExists(index);
129 return data[index];
130 }
131
132 /**
133 * Adds a primitive value to this collection.
134 *
135 * @param index the index to insert at
136 * @param value the value to add to this collection
137 * @return <code>true</code> if this collection was modified by this method call
138 * @throws IndexOutOfBoundsException if the index is invalid
139 */
140 public boolean add(int index, char value) {
141 checkAddModifiable();
142 checkIndex(index);
143 ensureCapacity(size + 1);
144 System.arraycopy(data, index, data, index + 1, size - index);
145 data[index] = value;
146 size++;
147 return true;
148 }
149
150 /**
151 * Removes a primitive value by index from the list.
152 *
153 * @param index the index to remove from
154 * @return the primitive value previously at this index
155 * @throws IndexOutOfBoundsException if the index is invalid
156 */
157 public char removeCharAt(int index) {
158 checkRemoveModifiable();
159 checkIndexExists(index);
160 char result = data[index];
161 System.arraycopy(data, index + 1, data, index, size - 1 - index);
162 size--;
163 return result;
164 }
165
166 /**
167 * Removes a range of values from the list.
168 *
169 * @param fromIndexInclusive the start of the range to remove, inclusive
170 * @param toIndexExclusive the end of the range to remove, exclusive
171 * @return <code>true</code> if the collection was modified
172 */
173 public boolean removeRange(int fromIndexInclusive, int toIndexExclusive) {
174 checkRemoveModifiable();
175 checkRange(fromIndexInclusive, toIndexExclusive);
176 if (fromIndexInclusive == toIndexExclusive) {
177 return false;
178 }
179 System.arraycopy(data, toIndexExclusive, data, fromIndexInclusive, size - toIndexExclusive);
180 size -= (toIndexExclusive - fromIndexInclusive);
181 return true;
182 }
183
184 /**
185 * Sets the primitive value at a specified index.
186 *
187 * @param index the index to set
188 * @param value the value to store
189 * @return the previous value at the index
190 * @throws IndexOutOfBoundsException if the index is invalid
191 */
192 public char set(int index, char value) {
193 checkSetModifiable();
194 checkIndexExists(index);
195 char result = data[index];
196 data[index] = value;
197 return result;
198 }
199
200 // Overrides
201 //-----------------------------------------------------------------------
202 /**
203 * Optimizes the implementation.
204 * <p>
205 * This implementation changes the internal array to be the same size as
206 * the size of the collection.
207 */
208 public void optimize() {
209 if (size < data.length) {
210 char[] array = new char[size];
211 System.arraycopy(data, 0, array, 0, size);
212 data = array;
213 }
214 }
215
216 /**
217 * Clears the collection/map of all elements.
218 * <p>
219 * This implementation resets the size, but does not reduce the internal storage array.
220 * <p>
221 * The collection/map will have a zero size after this method completes.
222 */
223 public void clear() {
224 size = 0;
225 }
226
227 /**
228 * Checks whether this collection contains a specified primitive value.
229 * <p>
230 * This implementation accesses the internal storage array directly.
231 *
232 * @param value the value to search for
233 * @return <code>true</code> if the value is found
234 */
235 public boolean contains(char value) {
236 for (int i = 0; i < size; i++) {
237 if (data[i] == value) {
238 return true;
239 }
240 }
241 return false;
242 }
243
244 /**
245 * Adds an array of primitive values to this collection at a specified index.
246 *
247 * @param index the index to add at
248 * @param values the values to add to this collection
249 * @return <code>true</code> if this collection was modified by this method call
250 * @throws IndexOutOfBoundsException if the index is invalid
251 */
252 public boolean addAll(int index, char[] values) {
253 checkAddModifiable();
254 checkIndex(index);
255 if (values == null || values.length == 0) {
256 return false;
257 }
258 int len = values.length;
259 ensureCapacity(size + len);
260 System.arraycopy(data, index, data, index + len, size - index);
261 System.arraycopy(values, 0, data, index, len);
262 size += len;
263 return true;
264 }
265
266 /**
267 * Gets the contents of the list as a String.
268 *
269 * @return the list contents
270 */
271 public String toStringContents() {
272 return new String(data, 0, size);
273 }
274
275 //-----------------------------------------------------------------------
276 /**
277 * Are the add methods supported.
278 *
279 * @return <code>true</code>
280 */
281 protected boolean isAddModifiable() {
282 return true;
283 }
284
285 /**
286 * Are the remove methods supported.
287 *
288 * @return <code>true</code>
289 */
290 protected boolean isRemoveModifiable() {
291 return true;
292 }
293
294 /**
295 * Are the remove methods supported.
296 *
297 * @return <code>true</code>
298 */
299 protected boolean isSetModifiable() {
300 return true;
301 }
302
303 /**
304 * Checks whether the object can currently be modified.
305 *
306 * @return <code>true</code>
307 */
308 public boolean isModifiable() {
309 return true;
310 }
311
312 /**
313 * Clone implementation that calls Object clone().
314 *
315 * @return the clone
316 */
317 public Object clone() {
318 ArrayCharList cloned = (ArrayCharList) super.clone();
319 cloned.data = (char[]) data.clone();
320 return cloned;
321 }
322
323 /**
324 * Copies data from this collection into the specified array.
325 * This method is pre-validated.
326 *
327 * @param fromIndex the index to start from
328 * @param dest the destination array
329 * @param destIndex the destination start index
330 * @param size the number of items to copy
331 */
332 protected void arrayCopy(int fromIndex, char[] dest, int destIndex, int size) {
333 System.arraycopy(data, fromIndex, dest, destIndex, size);
334 }
335
336 // Internal implementation
337 //-----------------------------------------------------------------------
338 /**
339 * Ensures that the internal storage array has at least the specified size.
340 *
341 * @param capacity the amount to expand to
342 */
343 protected void ensureCapacity(int capacity) {
344 int len = data.length;
345 if (capacity <= len) {
346 return;
347 }
348 int newLen = len * GROWTH_FACTOR_MULTIPLIER / GROWTH_FACTOR_DIVISOR;
349 if (newLen < capacity) {
350 newLen = capacity;
351 }
352 if (newLen < MIN_GROWTH_SIZE) {
353 newLen = MIN_GROWTH_SIZE;
354 }
355 char[] newArray = new char[newLen];
356 System.arraycopy(data, 0, newArray, 0, len);
357 data = newArray;
358 }
359
360 }
361