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 DoubleList} backed by an array of <code>double</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   */
33  public class ArrayDoubleList extends RandomAccessDoubleList implements DoubleList, Serializable {
34  
35      // constructors
36      //-------------------------------------------------------------------------
37  
38      /** 
39       * Construct an empty list with the default
40       * initial capacity.
41       */
42      public ArrayDoubleList() {
43          this(8);
44      }    
45  
46      /**
47       * Construct an empty list with the given
48       * initial capacity.
49       * @throws IllegalArgumentException when <i>initialCapacity</i> is negative
50       */
51      public ArrayDoubleList(int initialCapacity) {
52          if(initialCapacity < 0) {
53              throw new IllegalArgumentException("capacity " + initialCapacity);
54          }
55          _data = new double[initialCapacity];
56          _size = 0;
57      }    
58  
59      /** 
60       * Constructs a list containing the elements of the given collection, 
61       * in the order they are returned by that collection's iterator.
62       * 
63       * @see ArrayDoubleList#addAll(org.apache.commons.collections.primitives.DoubleCollection)
64       * @param that the non-<code>null</code> collection of <code>double</code>s 
65       *        to add
66       * @throws NullPointerException if <i>that</i> is <code>null</code>
67       */
68      public ArrayDoubleList(DoubleCollection that) { 
69          this(that.size());
70          addAll(that);
71      }    
72  
73      /**
74       * Constructs a list by copying the specified array.
75       * 
76       * @param array  the array to initialize the collection with
77       * @throws NullPointerException if the array is <code>null</code>
78       */
79      public ArrayDoubleList(double[] array) { 
80          this(array.length);
81          System.arraycopy(array, 0, _data, 0, array.length);
82          _size = array.length;
83      }
84  
85      // DoubleList methods
86      //-------------------------------------------------------------------------
87  
88      public double get(int index) {
89          checkRange(index);
90          return _data[index];
91      }
92      
93      public int size() {
94          return _size;
95      }
96      
97      /** 
98       * Removes the element at the specified position in 
99       * (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 double removeElementAt(int index) {
111         checkRange(index);
112         incrModCount();
113         double 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 double set(int index, double element) {
136         checkRange(index);
137         incrModCount();
138         double 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, double 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(DoubleCollection collection) {
174         return addAll(size(), collection);
175     }
176 
177     public boolean addAll(int index, DoubleCollection 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 (DoubleIterator 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             double[] olddata = _data;
209             _data = new double[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             double[] olddata = _data;
222             _data = new double[_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.writeDouble(_data[i]);
235         }
236     }
237 
238     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
239         in.defaultReadObject();
240         _data = new double[in.readInt()];
241         for(int i=0;i<_size;i++) {
242             _data[i] = in.readDouble();
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 double[] _data = null;
262     private int _size = 0;
263 
264 }