001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.collections.primitives;
018
019 import java.io.IOException;
020 import java.io.ObjectInputStream;
021 import java.io.ObjectOutputStream;
022 import java.io.Serializable;
023
024 /**
025 * An {@link LongList} backed by an array of <code>long</code>s.
026 * This implementation supports all optional methods.
027 *
028 * @since Commons Primitives 1.0
029 * @version $Revision: 480460 $ $Date: 2006-11-29 09:14:21 +0100 (Wed, 29 Nov 2006) $
030 *
031 * @author Rodney Waldhoff
032 */
033 public class ArrayLongList extends RandomAccessLongList implements LongList, Serializable {
034
035 // constructors
036 //-------------------------------------------------------------------------
037
038 /**
039 * Construct an empty list with the default
040 * initial capacity.
041 */
042 public ArrayLongList() {
043 this(8);
044 }
045
046 /**
047 * Construct an empty list with the given
048 * initial capacity.
049 * @throws IllegalArgumentException when <i>initialCapacity</i> is negative
050 */
051 public ArrayLongList(int initialCapacity) {
052 if(initialCapacity < 0) {
053 throw new IllegalArgumentException("capacity " + initialCapacity);
054 }
055 _data = new long[initialCapacity];
056 _size = 0;
057 }
058
059 /**
060 * Constructs a list containing the elements of the given collection,
061 * in the order they are returned by that collection's iterator.
062 *
063 * @see ArrayLongList#addAll(org.apache.commons.collections.primitives.LongCollection)
064 * @param that the non-<code>null</code> collection of <code>long</code>s
065 * to add
066 * @throws NullPointerException if <i>that</i> is <code>null</code>
067 */
068 public ArrayLongList(LongCollection that) {
069 this(that.size());
070 addAll(that);
071 }
072
073 /**
074 * Constructs a list by copying the specified array.
075 *
076 * @param array the array to initialize the collection with
077 * @throws NullPointerException if the array is <code>null</code>
078 */
079 public ArrayLongList(long[] array) {
080 this(array.length);
081 System.arraycopy(array, 0, _data, 0, array.length);
082 _size = array.length;
083 }
084
085 // LongList methods
086 //-------------------------------------------------------------------------
087
088 public long get(int index) {
089 checkRange(index);
090 return _data[index];
091 }
092
093 public int size() {
094 return _size;
095 }
096
097 /**
098 * Removes the element at the specified position in
099 * (optional operation). Any subsequent elements
100 * are shifted to the left, subtracting one from their
101 * indices. Returns the element that was removed.
102 *
103 * @param index the index of the element to remove
104 * @return the value of the element that was removed
105 *
106 * @throws UnsupportedOperationException when this operation is not
107 * supported
108 * @throws IndexOutOfBoundsException if the specified index is out of range
109 */
110 public long removeElementAt(int index) {
111 checkRange(index);
112 incrModCount();
113 long oldval = _data[index];
114 int numtomove = _size - index - 1;
115 if(numtomove > 0) {
116 System.arraycopy(_data,index+1,_data,index,numtomove);
117 }
118 _size--;
119 return oldval;
120 }
121
122 /**
123 * Replaces the element at the specified
124 * position in me with the specified element
125 * (optional operation).
126 *
127 * @param index the index of the element to change
128 * @param element the value to be stored at the specified position
129 * @return the value previously stored at the specified position
130 *
131 * @throws UnsupportedOperationException when this operation is not
132 * supported
133 * @throws IndexOutOfBoundsException if the specified index is out of range
134 */
135 public long set(int index, long element) {
136 checkRange(index);
137 incrModCount();
138 long oldval = _data[index];
139 _data[index] = element;
140 return oldval;
141 }
142
143 /**
144 * Inserts the specified element at the specified position
145 * (optional operation). Shifts the element currently
146 * at that position (if any) and any subsequent elements to the
147 * right, increasing their indices.
148 *
149 * @param index the index at which to insert the element
150 * @param element the value to insert
151 *
152 * @throws UnsupportedOperationException when this operation is not
153 * supported
154 * @throws IllegalArgumentException if some aspect of the specified element
155 * prevents it from being added to me
156 * @throws IndexOutOfBoundsException if the specified index is out of range
157 */
158 public void add(int index, long element) {
159 checkRangeIncludingEndpoint(index);
160 incrModCount();
161 ensureCapacity(_size+1);
162 int numtomove = _size-index;
163 System.arraycopy(_data,index,_data,index+1,numtomove);
164 _data[index] = element;
165 _size++;
166 }
167
168 public void clear() {
169 incrModCount();
170 _size = 0;
171 }
172
173 public boolean addAll(LongCollection collection) {
174 return addAll(size(), collection);
175 }
176
177 public boolean addAll(int index, LongCollection collection) {
178 if (collection.size() == 0) {
179 return false;
180 }
181 checkRangeIncludingEndpoint(index);
182 incrModCount();
183 ensureCapacity(_size + collection.size());
184 if (index != _size) {
185 // Need to move some elements
186 System.arraycopy(_data, index, _data, index + collection.size(), _size - index);
187 }
188 for (LongIterator it = collection.iterator(); it.hasNext();) {
189 _data[index] = it.next();
190 index++;
191 }
192 _size += collection.size();
193 return true;
194 }
195
196 // capacity methods
197 //-------------------------------------------------------------------------
198
199 /**
200 * Increases my capacity, if necessary, to ensure that I can hold at
201 * least the number of elements specified by the minimum capacity
202 * argument without growing.
203 */
204 public void ensureCapacity(int mincap) {
205 incrModCount();
206 if(mincap > _data.length) {
207 int newcap = (_data.length * 3)/2 + 1;
208 long[] olddata = _data;
209 _data = new long[newcap < mincap ? mincap : newcap];
210 System.arraycopy(olddata,0,_data,0,_size);
211 }
212 }
213
214 /**
215 * Reduce my capacity, if necessary, to match my
216 * current {@link #size size}.
217 */
218 public void trimToSize() {
219 incrModCount();
220 if(_size < _data.length) {
221 long[] olddata = _data;
222 _data = new long[_size];
223 System.arraycopy(olddata,0,_data,0,_size);
224 }
225 }
226
227 // private methods
228 //-------------------------------------------------------------------------
229
230 private void writeObject(ObjectOutputStream out) throws IOException{
231 out.defaultWriteObject();
232 out.writeInt(_data.length);
233 for(int i=0;i<_size;i++) {
234 out.writeLong(_data[i]);
235 }
236 }
237
238 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
239 in.defaultReadObject();
240 _data = new long[in.readInt()];
241 for(int i=0;i<_size;i++) {
242 _data[i] = in.readLong();
243 }
244 }
245
246 private final void checkRange(int index) {
247 if(index < 0 || index >= _size) {
248 throw new IndexOutOfBoundsException("Should be at least 0 and less than " + _size + ", found " + index);
249 }
250 }
251
252 private final void checkRangeIncludingEndpoint(int index) {
253 if(index < 0 || index > _size) {
254 throw new IndexOutOfBoundsException("Should be at least 0 and at most " + _size + ", found " + index);
255 }
256 }
257
258 // attributes
259 //-------------------------------------------------------------------------
260
261 private transient long[] _data = null;
262 private int _size = 0;
263
264 }