1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections.primitives;
18
19 import java.util.ConcurrentModificationException;
20 import java.util.NoSuchElementException;
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 public abstract class RandomAccessCharList extends AbstractCharCollection implements CharList {
41
42
43
44
45
46 protected RandomAccessCharList() {
47 }
48
49
50
51
52 public abstract char get(int index);
53 public abstract int size();
54
55
56
57
58
59
60
61
62 public char removeElementAt(int index) {
63 throw new UnsupportedOperationException();
64 }
65
66
67
68
69
70 public char set(int index, char element) {
71 throw new UnsupportedOperationException();
72 }
73
74
75
76
77
78 public void add(int index, char element) {
79 throw new UnsupportedOperationException();
80 }
81
82
83
84
85
86 public boolean add(char element) {
87 add(size(),element);
88 return true;
89 }
90
91 public boolean addAll(int index, CharCollection collection) {
92 boolean modified = false;
93 for(CharIterator iter = collection.iterator(); iter.hasNext(); ) {
94 add(index++,iter.next());
95 modified = true;
96 }
97 return modified;
98 }
99
100 public int indexOf(char element) {
101 int i = 0;
102 for(CharIterator iter = iterator(); iter.hasNext(); ) {
103 if(iter.next() == element) {
104 return i;
105 } else {
106 i++;
107 }
108 }
109 return -1;
110 }
111
112 public int lastIndexOf(char element) {
113 for(CharListIterator iter = listIterator(size()); iter.hasPrevious(); ) {
114 if(iter.previous() == element) {
115 return iter.nextIndex();
116 }
117 }
118 return -1;
119 }
120
121 public CharIterator iterator() {
122 return listIterator();
123 }
124
125 public CharListIterator listIterator() {
126 return listIterator(0);
127 }
128
129 public CharListIterator listIterator(int index) {
130 return new RandomAccessCharListIterator(this,index);
131 }
132
133 public CharList subList(int fromIndex, int toIndex) {
134 return new RandomAccessCharSubList(this,fromIndex,toIndex);
135 }
136
137 public boolean equals(Object that) {
138 if(this == that) {
139 return true;
140 } else if(that instanceof CharList) {
141 CharList thatList = (CharList)that;
142 if(size() != thatList.size()) {
143 return false;
144 }
145 for(CharIterator thatIter = thatList.iterator(), thisIter = iterator(); thisIter.hasNext();) {
146 if(thisIter.next() != thatIter.next()) {
147 return false;
148 }
149 }
150 return true;
151 } else {
152 return false;
153 }
154 }
155
156 public int hashCode() {
157 int hash = 1;
158 for(CharIterator iter = iterator(); iter.hasNext(); ) {
159 hash = 31*hash + iter.next();
160 }
161 return hash;
162 }
163
164 public String toString() {
165
166 return new String(toArray());
167 }
168
169
170
171
172
173 protected int getModCount() {
174 return _modCount;
175 }
176
177
178 protected void incrModCount() {
179 _modCount++;
180 }
181
182
183
184
185 private int _modCount = 0;
186
187
188
189
190 private static class ComodChecker {
191 ComodChecker(RandomAccessCharList source) {
192 _source = source;
193 resyncModCount();
194 }
195
196 protected RandomAccessCharList getList() {
197 return _source;
198 }
199
200 protected void assertNotComodified() throws ConcurrentModificationException {
201 if(_expectedModCount != getList().getModCount()) {
202 throw new ConcurrentModificationException();
203 }
204 }
205
206 protected void resyncModCount() {
207 _expectedModCount = getList().getModCount();
208 }
209
210 private RandomAccessCharList _source = null;
211 private int _expectedModCount = -1;
212 }
213
214 protected static class RandomAccessCharListIterator extends ComodChecker implements CharListIterator {
215 RandomAccessCharListIterator(RandomAccessCharList list, int index) {
216 super(list);
217 if(index < 0 || index > getList().size()) {
218 throw new IndexOutOfBoundsException("Index " + index + " not in [0," + getList().size() + ")");
219 } else {
220 _nextIndex = index;
221 resyncModCount();
222 }
223 }
224
225 public boolean hasNext() {
226 assertNotComodified();
227 return _nextIndex < getList().size();
228 }
229
230 public boolean hasPrevious() {
231 assertNotComodified();
232 return _nextIndex > 0;
233 }
234
235 public int nextIndex() {
236 assertNotComodified();
237 return _nextIndex;
238 }
239
240 public int previousIndex() {
241 assertNotComodified();
242 return _nextIndex - 1;
243 }
244
245 public char next() {
246 assertNotComodified();
247 if(!hasNext()) {
248 throw new NoSuchElementException();
249 } else {
250 char val = getList().get(_nextIndex);
251 _lastReturnedIndex = _nextIndex;
252 _nextIndex++;
253 return val;
254 }
255 }
256
257 public char previous() {
258 assertNotComodified();
259 if(!hasPrevious()) {
260 throw new NoSuchElementException();
261 } else {
262 char val = getList().get(_nextIndex-1);
263 _lastReturnedIndex = _nextIndex-1;
264 _nextIndex--;
265 return val;
266 }
267 }
268
269 public void add(char value) {
270 assertNotComodified();
271 getList().add(_nextIndex,value);
272 _nextIndex++;
273 _lastReturnedIndex = -1;
274 resyncModCount();
275 }
276
277 public void remove() {
278 assertNotComodified();
279 if (_lastReturnedIndex == -1) {
280 throw new IllegalStateException();
281 }
282 if (_lastReturnedIndex == _nextIndex) {
283
284 getList().removeElementAt(_lastReturnedIndex);
285 } else {
286
287 getList().removeElementAt(_lastReturnedIndex);
288 _nextIndex--;
289 }
290 _lastReturnedIndex = -1;
291 resyncModCount();
292 }
293
294 public void set(char value) {
295 assertNotComodified();
296 if(-1 == _lastReturnedIndex) {
297 throw new IllegalStateException();
298 } else {
299 getList().set(_lastReturnedIndex,value);
300 resyncModCount();
301 }
302 }
303
304 private int _nextIndex = 0;
305 private int _lastReturnedIndex = -1;
306 }
307
308 protected static class RandomAccessCharSubList extends RandomAccessCharList implements CharList {
309 RandomAccessCharSubList(RandomAccessCharList list, int fromIndex, int toIndex) {
310 if(fromIndex < 0 || toIndex > list.size()) {
311 throw new IndexOutOfBoundsException();
312 } else if(fromIndex > toIndex) {
313 throw new IllegalArgumentException();
314 } else {
315 _list = list;
316 _offset = fromIndex;
317 _limit = toIndex - fromIndex;
318 _comod = new ComodChecker(list);
319 _comod.resyncModCount();
320 }
321 }
322
323 public char get(int index) {
324 checkRange(index);
325 _comod.assertNotComodified();
326 return _list.get(toUnderlyingIndex(index));
327 }
328
329 public char removeElementAt(int index) {
330 checkRange(index);
331 _comod.assertNotComodified();
332 char val = _list.removeElementAt(toUnderlyingIndex(index));
333 _limit--;
334 _comod.resyncModCount();
335 incrModCount();
336 return val;
337 }
338
339 public char set(int index, char element) {
340 checkRange(index);
341 _comod.assertNotComodified();
342 char val = _list.set(toUnderlyingIndex(index),element);
343 incrModCount();
344 _comod.resyncModCount();
345 return val;
346 }
347
348 public void add(int index, char element) {
349 checkRangeIncludingEndpoint(index);
350 _comod.assertNotComodified();
351 _list.add(toUnderlyingIndex(index),element);
352 _limit++;
353 _comod.resyncModCount();
354 incrModCount();
355 }
356
357 public int size() {
358 _comod.assertNotComodified();
359 return _limit;
360 }
361
362 private void checkRange(int index) {
363 if(index < 0 || index >= size()) {
364 throw new IndexOutOfBoundsException("index " + index + " not in [0," + size() + ")");
365 }
366 }
367
368 private void checkRangeIncludingEndpoint(int index) {
369 if(index < 0 || index > size()) {
370 throw new IndexOutOfBoundsException("index " + index + " not in [0," + size() + "]");
371 }
372 }
373
374 private int toUnderlyingIndex(int index) {
375 return (index + _offset);
376 }
377
378 private int _offset = 0;
379 private int _limit = 0;
380 private RandomAccessCharList _list = null;
381 private ComodChecker _comod = null;
382
383 }
384 }
385