View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections.primitives;
18  
19  import java.io.IOException;
20  import java.io.ObjectInputStream;
21  import java.io.ObjectOutputStream;
22  import java.io.Serializable;
23  
24  /**
25   * An {@link IntList} backed by an array of <code>int</code>s.
26   * This implementation supports all optional methods.
27   * 
28   * @since Commons Primitives 1.0
29   * @version $Revision: 480460 $ $Date: 2006-11-29 03:14:21 -0500 (Wed, 29 Nov 2006) $
30   * 
31   * @author Rodney Waldhoff
32   * @author Robert Fischer
33   */
34  public class ArrayIntList extends RandomAccessIntList implements IntList, Serializable {
35  
36      // constructors
37      //-------------------------------------------------------------------------
38  
39      /** 
40       * Construct an empty list with the default
41       * initial capacity.
42       */
43      public ArrayIntList() {
44          this(8);
45      }    
46  
47      /**
48       * Construct an empty list with the given
49       * initial capacity.
50       * @throws IllegalArgumentException when <i>initialCapacity</i> is negative
51       */
52      public ArrayIntList(int initialCapacity) {
53          if(initialCapacity < 0) {
54              throw new IllegalArgumentException("capacity " + initialCapacity);
55          }
56          _data = new int[initialCapacity];
57          _size = 0;
58      }    
59  
60      /** 
61       * Constructs a list containing the elements of the given collection, 
62       * in the order they are returned by that collection's iterator.
63       * 
64       * @see ArrayIntList#addAll(org.apache.commons.collections.primitives.IntCollection)
65       * @param that the non-<code>null</code> collection of <code>int</code>s 
66       *        to add
67       * @throws NullPointerException if <i>that</i> is <code>null</code>
68       */
69      public ArrayIntList(IntCollection that) { 
70          this(that.size());
71          addAll(that);
72      }    
73  
74      /**
75       * Constructs a list by copying the specified array.
76       * 
77       * @param array  the array to initialize the collection with
78       * @throws NullPointerException if the array is <code>null</code>
79       */
80      public ArrayIntList(int[] array) { 
81          this(array.length);
82          System.arraycopy(array, 0, _data, 0, array.length);
83          _size = array.length;
84      }
85  
86      // IntList methods
87      //-------------------------------------------------------------------------
88  
89      public int get(int index) {
90          checkRange(index);
91          return _data[index];
92      }
93      
94      public int size() {
95          return _size;
96      }
97      
98      /** 
99       * Removes the element at the specified position in 
100      * (optional operation).  Any subsequent elements 
101      * are shifted to the left, subtracting one from their 
102      * indices.  Returns the element that was removed.
103      * 
104      * @param index the index of the element to remove
105      * @return the value of the element that was removed
106      * 
107      * @throws UnsupportedOperationException when this operation is not 
108      *         supported
109      * @throws IndexOutOfBoundsException if the specified index is out of range
110      */
111     public int removeElementAt(int index) {
112         checkRange(index);
113         incrModCount();
114         int oldval = _data[index];
115         int numtomove = _size - index - 1;
116         if(numtomove > 0) {
117             System.arraycopy(_data,index+1,_data,index,numtomove);
118         }
119         _size--;
120         return oldval;
121     }
122     
123     /** 
124      * Replaces the element at the specified 
125      * position in me with the specified element
126      * (optional operation). 
127      * 
128      * @param index the index of the element to change
129      * @param element the value to be stored at the specified position
130      * @return the value previously stored at the specified position
131      * 
132      * @throws UnsupportedOperationException when this operation is not 
133      *         supported
134      * @throws IndexOutOfBoundsException if the specified index is out of range
135      */
136     public int set(int index, int element) {
137         checkRange(index);
138         incrModCount();
139         int oldval = _data[index];
140         _data[index] = element;
141         return oldval;
142     }
143         
144     /** 
145      * Inserts the specified element at the specified position 
146      * (optional operation). Shifts the element currently 
147      * at that position (if any) and any subsequent elements to the 
148      * right, increasing their indices.
149      * 
150      * @param index the index at which to insert the element
151      * @param element the value to insert
152      * 
153      * @throws UnsupportedOperationException when this operation is not 
154      *         supported
155      * @throws IllegalArgumentException if some aspect of the specified element 
156      *         prevents it from being added to me
157      * @throws IndexOutOfBoundsException if the specified index is out of range
158      */
159     public void add(int index, int element) {
160         checkRangeIncludingEndpoint(index);
161         incrModCount();
162         ensureCapacity(_size+1);
163         int numtomove = _size-index;
164         System.arraycopy(_data,index,_data,index+1,numtomove);
165         _data[index] = element;
166         _size++;
167     }
168 
169     public void clear() {
170         incrModCount();
171         _size = 0;
172     }
173 
174     public boolean addAll(IntCollection collection) {
175 		return addAll(size(), collection);
176 	}
177 
178 	public boolean addAll(int index, IntCollection collection) {
179 		if (collection.size() == 0) {
180 			return false;
181         }
182 		checkRangeIncludingEndpoint(index);
183 		incrModCount();
184 		ensureCapacity(_size + collection.size());
185 		if (index != _size) {
186 			// Need to move some elements
187 			System.arraycopy(_data, index, _data, index + collection.size(), _size - index);
188 		}
189 		for (IntIterator it = collection.iterator(); it.hasNext();) {
190 			_data[index] = it.next();
191 			index++;
192 		}
193 		_size += collection.size();
194 		return true;
195 	}
196 
197     // capacity methods
198     //-------------------------------------------------------------------------
199 
200     /** 
201      * Increases my capacity, if necessary, to ensure that I can hold at 
202      * least the number of elements specified by the minimum capacity 
203      * argument without growing.
204      */
205     public void ensureCapacity(int mincap) {
206         incrModCount();
207         if(mincap > _data.length) {
208             int newcap = (_data.length * 3)/2 + 1;
209             int[] olddata = _data;
210             _data = new int[newcap < mincap ? mincap : newcap];
211             System.arraycopy(olddata,0,_data,0,_size);
212         }
213     }
214 
215     /** 
216      * Reduce my capacity, if necessary, to match my
217      * current {@link #size size}.
218      */
219     public void trimToSize() {
220         incrModCount();
221         if(_size < _data.length) {
222             int[] olddata = _data;
223             _data = new int[_size];
224             System.arraycopy(olddata,0,_data,0,_size);
225         }
226     }
227 
228     // private methods
229     //-------------------------------------------------------------------------
230     
231     private void writeObject(ObjectOutputStream out) throws IOException{
232         out.defaultWriteObject();
233         out.writeInt(_data.length);
234         for(int i=0;i<_size;i++) {
235             out.writeInt(_data[i]);
236         }
237     }
238 
239     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
240         in.defaultReadObject();
241         _data = new int[in.readInt()];
242         for(int i=0;i<_size;i++) {
243             _data[i] = in.readInt();
244         }
245     }
246     
247     private final void checkRange(int index) {
248         if(index < 0 || index >= _size) {
249             throw new IndexOutOfBoundsException("Should be at least 0 and less than " + _size + ", found " + index);
250         }
251     }
252 
253     private final void checkRangeIncludingEndpoint(int index) {
254         if(index < 0 || index > _size) {
255             throw new IndexOutOfBoundsException("Should be at least 0 and at most " + _size + ", found " + index);
256         }
257     }
258 
259     // attributes
260     //-------------------------------------------------------------------------
261     
262     private transient int[] _data = null;
263     private int _size = 0;
264 
265 }