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 */ 017package org.apache.commons.collections.primitives; 018 019import java.io.IOException; 020import java.io.ObjectInputStream; 021import java.io.ObjectOutputStream; 022import java.io.Serializable; 023 024/** 025 * An {@link BooleanList} backed by an array of <code>boolean</code>s. 026 * This implementation supports all optional methods. 027 * 028 * @since Commons Primitives 1.1 029 * @version $Revision: 480460 $ $Date: 2006-11-29 03:14:21 -0500 (Wed, 29 Nov 2006) $ 030 */ 031public class ArrayBooleanList extends RandomAccessBooleanList 032 implements BooleanList, Serializable { 033 034 // constructors 035 //------------------------------------------------------------------------- 036 037 /** 038 * Construct an empty list with the default 039 * initial capacity. 040 */ 041 public ArrayBooleanList() { 042 this(8); 043 } 044 045 /** 046 * Construct an empty list with the given 047 * initial capacity. 048 * @throws IllegalArgumentException when <i>initialCapacity</i> is negative 049 */ 050 public ArrayBooleanList(int initialCapacity) { 051 if(initialCapacity < 0) { 052 throw new IllegalArgumentException("capacity " + initialCapacity); 053 } 054 _data = new boolean[initialCapacity]; 055 _size = 0; 056 } 057 058 /** 059 * Constructs a list containing the elements of the given collection, 060 * in the order they are returned by that collection's iterator. 061 * 062 * @see ArrayBooleanList#addAll(BooleanCollection) 063 * @param that the non-<code>null</code> collection of <code>boolean</code>s 064 * to add 065 * @throws NullPointerException if <i>that</i> is <code>null</code> 066 */ 067 public ArrayBooleanList(BooleanCollection that) { 068 this(that.size()); 069 addAll(that); 070 } 071 072 /** 073 * Constructs a list by copying the specified array. 074 * 075 * @param array the array to initialize the collection with 076 * @throws NullPointerException if the array is <code>null</code> 077 */ 078 public ArrayBooleanList(boolean[] array) { 079 this(array.length); 080 System.arraycopy(array, 0, _data, 0, array.length); 081 _size = array.length; 082 } 083 084 // BooleanList methods 085 //------------------------------------------------------------------------- 086 087 public boolean get(int index) { 088 checkRange(index); 089 return _data[index]; 090 } 091 092 public int size() { 093 return _size; 094 } 095 096 /** 097 * Removes the element at the specified position in (optional operation). 098 * Any subsequent elements are shifted to the left, subtracting one from 099 * 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}