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.LongUtils;
021    
022    /**
023     * Array based implementation of <code>LongList</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 ArrayLongList extends AbstractLongList 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 long[] data;
049        /** The current size */
050        private int size;
051    
052        /**
053         * Constructor.
054         */
055        public ArrayLongList() {
056            super();
057            data = LongUtils.EMPTY_LONG_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 ArrayLongList(int initialSize) {
066            super();
067            if (initialSize <= 0) {
068                data = LongUtils.EMPTY_LONG_ARRAY;
069            } else {
070                data = new long[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 ArrayLongList(long[] values) {
080            super();
081            if (values == null) {
082                data = LongUtils.EMPTY_LONG_ARRAY;
083            } else {
084                data = (long[]) 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 ArrayLongList(Collection<Long> coll) {
095            super();
096            if (coll == null) {
097                data = LongUtils.EMPTY_LONG_ARRAY;
098            } else if (coll instanceof ArrayLongList) {
099                ArrayLongList c = (ArrayLongList) coll;
100                this.data = new long[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 long getLong(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, long 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 long removeLongAt(int index) {
158            checkRemoveModifiable();
159            checkIndexExists(index);
160            long 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 long set(int index, long value) {
193            checkSetModifiable();
194            checkIndexExists(index);
195            long 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                long[] array = new long[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(long 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, long[] 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        /**
268         * Are the add methods supported.
269         *
270         * @return <code>true</code>
271         */
272        protected boolean isAddModifiable() {
273            return true;
274        }
275    
276        /**
277         * Are the remove methods supported.
278         *
279         * @return <code>true</code>
280         */
281        protected boolean isRemoveModifiable() {
282            return true;
283        }
284    
285        /**
286         * Are the remove methods supported.
287         *
288         * @return <code>true</code>
289         */
290        protected boolean isSetModifiable() {
291            return true;
292        }
293    
294        /**
295         * Checks whether the object can currently be modified.
296         *
297         * @return <code>true</code>
298         */
299        public boolean isModifiable() {
300            return true;
301        }
302    
303        /**
304         * Clone implementation that calls Object clone().
305         * 
306         * @return the clone
307         */
308        public Object clone() {
309            ArrayLongList cloned = (ArrayLongList) super.clone();
310            cloned.data = (long[]) data.clone();
311            return cloned;
312        }
313    
314        /**
315         * Copies data from this collection into the specified array.
316         * This method is pre-validated.
317         * 
318         * @param fromIndex  the index to start from
319         * @param dest  the destination array
320         * @param destIndex  the destination start index
321         * @param size  the number of items to copy
322         */
323        protected void arrayCopy(int fromIndex, long[] dest, int destIndex, int size) {
324            System.arraycopy(data, fromIndex, dest, destIndex, size);
325        }
326    
327        // Internal implementation
328        //-----------------------------------------------------------------------
329        /**
330         * Ensures that the internal storage array has at least the specified size.
331         * 
332         * @param capacity  the amount to expand to
333         */
334        protected void ensureCapacity(int capacity) {
335            int len = data.length;
336            if (capacity <= len) {
337                return;
338            }
339            int newLen = len * GROWTH_FACTOR_MULTIPLIER / GROWTH_FACTOR_DIVISOR;
340            if (newLen < capacity) {
341                newLen = capacity;
342            }
343            if (newLen < MIN_GROWTH_SIZE) {
344                newLen = MIN_GROWTH_SIZE;
345            }
346            long[] newArray = new long[newLen];
347            System.arraycopy(data, 0, newArray, 0, len);
348            data = newArray;
349        }
350    
351    }
352