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