Libraryless. Click here for Pure Java version (4360L/24K).
1 | // Modified from java.util.ArrayList |
2 | |
3 | sclass SynchronizedArrayList<A> extends SynchronizedArrayList_Base<A> implements RandomAccess, Cloneable { |
4 | private static final int DEFAULT_CAPACITY = 10; |
5 | private static final Object[] EMPTY_ELEMENTDATA = {}; |
6 | private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; |
7 | transient Object[] elementData; // non-private to simplify nested class access |
8 | private int size; |
9 | |
10 | *(int initialCapacity) { |
11 | if (initialCapacity > 0) { |
12 | this.elementData = new Object[initialCapacity]; |
13 | } else if (initialCapacity == 0) { |
14 | this.elementData = EMPTY_ELEMENTDATA; |
15 | } else { |
16 | throw new IllegalArgumentException("Illegal Capacity: "+ |
17 | initialCapacity); |
18 | } |
19 | } |
20 | |
21 | *() { |
22 | this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; |
23 | } |
24 | |
25 | *(Collection<? extends A> c) { |
26 | elementData = c.toArray(); |
27 | if ((size = elementData.length) != 0) { |
28 | // c.toArray might (incorrectly) not return Object[] (see 6260652) |
29 | if (elementData.getClass() != Object[].class) |
30 | elementData = Arrays.copyOf(elementData, size, Object[].class); |
31 | } else { |
32 | // replace with empty array. |
33 | this.elementData = EMPTY_ELEMENTDATA; |
34 | } |
35 | } |
36 | |
37 | public synchronized void trimToSize() { |
38 | modCount++; |
39 | if (size < elementData.length) { |
40 | elementData = (size == 0) |
41 | ? EMPTY_ELEMENTDATA |
42 | : Arrays.copyOf(elementData, size); |
43 | } |
44 | } |
45 | |
46 | public synchronized void ensureCapacity(int minCapacity) { |
47 | int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) |
48 | // any size if not default element table |
49 | ? 0 |
50 | // larger than default for default empty table. It's already |
51 | // supposed to be at default size. |
52 | : DEFAULT_CAPACITY; |
53 | |
54 | if (minCapacity > minExpand) { |
55 | ensureExplicitCapacity(minCapacity); |
56 | } |
57 | } |
58 | |
59 | private void ensureCapacityInternal(int minCapacity) { |
60 | if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { |
61 | minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); |
62 | } |
63 | |
64 | ensureExplicitCapacity(minCapacity); |
65 | } |
66 | |
67 | private void ensureExplicitCapacity(int minCapacity) { |
68 | modCount++; |
69 | |
70 | // overflow-conscious code |
71 | if (minCapacity - elementData.length > 0) |
72 | grow(minCapacity); |
73 | } |
74 | |
75 | private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; |
76 | |
77 | private void grow(int minCapacity) { |
78 | // overflow-conscious code |
79 | int oldCapacity = elementData.length; |
80 | int newCapacity = oldCapacity + (oldCapacity >> 1); |
81 | if (newCapacity - minCapacity < 0) |
82 | newCapacity = minCapacity; |
83 | if (newCapacity - MAX_ARRAY_SIZE > 0) |
84 | newCapacity = hugeCapacity(minCapacity); |
85 | // minCapacity is usually close to size, so this is a win: |
86 | elementData = Arrays.copyOf(elementData, newCapacity); |
87 | } |
88 | |
89 | private static int hugeCapacity(int minCapacity) { |
90 | if (minCapacity < 0) // overflow |
91 | throw new OutOfMemoryError(); |
92 | return (minCapacity > MAX_ARRAY_SIZE) ? |
93 | Integer.MAX_VALUE : |
94 | MAX_ARRAY_SIZE; |
95 | } |
96 | |
97 | public synchronized int size() { |
98 | return size; |
99 | } |
100 | |
101 | public synchronized boolean isEmpty() { |
102 | return size == 0; |
103 | } |
104 | |
105 | public boolean contains(Object o) { |
106 | return indexOf(o) >= 0; |
107 | } |
108 | |
109 | public synchronized int indexOf(Object o) { |
110 | if (o == null) { |
111 | for (int i = 0; i < size; i++) |
112 | if (elementData[i]==null) |
113 | return i; |
114 | } else { |
115 | for (int i = 0; i < size; i++) |
116 | if (o.equals(elementData[i])) |
117 | return i; |
118 | } |
119 | return -1; |
120 | } |
121 | |
122 | public synchronized int lastIndexOf(Object o) { |
123 | if (o == null) { |
124 | for (int i = size-1; i >= 0; i--) |
125 | if (elementData[i]==null) |
126 | return i; |
127 | } else { |
128 | for (int i = size-1; i >= 0; i--) |
129 | if (o.equals(elementData[i])) |
130 | return i; |
131 | } |
132 | return -1; |
133 | } |
134 | |
135 | public synchronized Object clone() { |
136 | ret new SynchronizedArrayList(this); |
137 | } |
138 | |
139 | public synchronized Object[] toArray() { |
140 | return Arrays.copyOf(elementData, size); |
141 | } |
142 | |
143 | @SuppressWarnings("unchecked") |
144 | public synchronized <T> T[] toArray(T[] a) { |
145 | if (a.length < size) |
146 | // Make a new array of a's runtime type, but my contents: |
147 | return (T[]) Arrays.copyOf(elementData, size, a.getClass()); |
148 | System.arraycopy(elementData, 0, a, 0, size); |
149 | if (a.length > size) |
150 | a[size] = null; |
151 | return a; |
152 | } |
153 | |
154 | // Positional Access Operations |
155 | |
156 | @SuppressWarnings("unchecked") |
157 | A elementData(int index) { |
158 | return (A) elementData[index]; |
159 | } |
160 | |
161 | public synchronized A get(int index) { |
162 | rangeCheck(index); |
163 | |
164 | return elementData(index); |
165 | } |
166 | |
167 | public synchronized A set(int index, A element) { |
168 | rangeCheck(index); |
169 | |
170 | A oldValue = elementData(index); |
171 | elementData[index] = element; |
172 | return oldValue; |
173 | } |
174 | |
175 | public synchronized boolean add(A e) { |
176 | ensureCapacityInternal(size + 1); // Increments modCount!! |
177 | elementData[size++] = e; |
178 | return true; |
179 | } |
180 | |
181 | public synchronized void add(int index, A element) { |
182 | rangeCheckForAdd(index); |
183 | |
184 | ensureCapacityInternal(size + 1); // Increments modCount!! |
185 | System.arraycopy(elementData, index, elementData, index + 1, |
186 | size - index); |
187 | elementData[index] = element; |
188 | size++; |
189 | } |
190 | |
191 | public synchronized A remove(int index) { |
192 | rangeCheck(index); |
193 | |
194 | modCount++; |
195 | A oldValue = elementData(index); |
196 | |
197 | int numMoved = size - index - 1; |
198 | if (numMoved > 0) |
199 | System.arraycopy(elementData, index+1, elementData, index, |
200 | numMoved); |
201 | elementData[--size] = null; // clear to let GC do its work |
202 | |
203 | return oldValue; |
204 | } |
205 | |
206 | public synchronized boolean remove(Object o) { |
207 | if (o == null) { |
208 | for (int index = 0; index < size; index++) |
209 | if (elementData[index] == null) { |
210 | fastRemove(index); |
211 | return true; |
212 | } |
213 | } else { |
214 | for (int index = 0; index < size; index++) |
215 | if (o.equals(elementData[index])) { |
216 | fastRemove(index); |
217 | return true; |
218 | } |
219 | } |
220 | return false; |
221 | } |
222 | |
223 | private void fastRemove(int index) { |
224 | modCount++; |
225 | int numMoved = size - index - 1; |
226 | if (numMoved > 0) |
227 | System.arraycopy(elementData, index+1, elementData, index, |
228 | numMoved); |
229 | elementData[--size] = null; // clear to let GC do its work |
230 | } |
231 | |
232 | public synchronized void clear() { |
233 | modCount++; |
234 | |
235 | // clear to let GC do its work |
236 | for (int i = 0; i < size; i++) |
237 | elementData[i] = null; |
238 | |
239 | size = 0; |
240 | } |
241 | |
242 | public synchronized boolean addAll(Collection<? extends A> c) { |
243 | Object[] a = c.toArray(); |
244 | int numNew = a.length; |
245 | ensureCapacityInternal(size + numNew); // Increments modCount |
246 | System.arraycopy(a, 0, elementData, size, numNew); |
247 | size += numNew; |
248 | return numNew != 0; |
249 | } |
250 | |
251 | public synchronized boolean addAll(int index, Collection<? extends A> c) { |
252 | rangeCheckForAdd(index); |
253 | |
254 | Object[] a = c.toArray(); |
255 | int numNew = a.length; |
256 | ensureCapacityInternal(size + numNew); // Increments modCount |
257 | |
258 | int numMoved = size - index; |
259 | if (numMoved > 0) |
260 | System.arraycopy(elementData, index, elementData, index + numNew, |
261 | numMoved); |
262 | |
263 | System.arraycopy(a, 0, elementData, index, numNew); |
264 | size += numNew; |
265 | return numNew != 0; |
266 | } |
267 | |
268 | public synchronized void removeRange(int fromIndex, int toIndex) { |
269 | modCount++; |
270 | int numMoved = size - toIndex; |
271 | System.arraycopy(elementData, toIndex, elementData, fromIndex, |
272 | numMoved); |
273 | |
274 | // clear to let GC do its work |
275 | int newSize = size - (toIndex-fromIndex); |
276 | for (int i = newSize; i < size; i++) { |
277 | elementData[i] = null; |
278 | } |
279 | size = newSize; |
280 | } |
281 | |
282 | private void rangeCheck(int index) { |
283 | if (index >= size) |
284 | throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); |
285 | } |
286 | |
287 | private void rangeCheckForAdd(int index) { |
288 | if (index > size || index < 0) |
289 | throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); |
290 | } |
291 | |
292 | /** |
293 | * Constructs an IndexOutOfBoundsException detail message. |
294 | * Of the many possible refactorings of the error handling code, |
295 | * this "outlining" performs best with both server and client VMs. |
296 | */ |
297 | private String outOfBoundsMsg(int index) { |
298 | return "Index: "+index+", Size: "+size; |
299 | } |
300 | |
301 | public synchronized boolean removeAll(Collection<?> c) { |
302 | Objects.requireNonNull(c); |
303 | return batchRemove(c, false); |
304 | } |
305 | |
306 | public synchronized boolean retainAll(Collection<?> c) { |
307 | Objects.requireNonNull(c); |
308 | return batchRemove(c, true); |
309 | } |
310 | |
311 | private boolean batchRemove(Collection<?> c, boolean complement) { |
312 | final Object[] elementData = this.elementData; |
313 | int r = 0, w = 0; |
314 | boolean modified = false; |
315 | try { |
316 | for (; r < size; r++) |
317 | if (c.contains(elementData[r]) == complement) |
318 | elementData[w++] = elementData[r]; |
319 | } finally { |
320 | // Preserve behavioral compatibility with AbstractCollection, |
321 | // even if c.contains() throws. |
322 | if (r != size) { |
323 | System.arraycopy(elementData, r, |
324 | elementData, w, |
325 | size - r); |
326 | w += size - r; |
327 | } |
328 | if (w != size) { |
329 | // clear to let GC do its work |
330 | for (int i = w; i < size; i++) |
331 | elementData[i] = null; |
332 | modCount += size - w; |
333 | size = w; |
334 | modified = true; |
335 | } |
336 | } |
337 | return modified; |
338 | } |
339 | |
340 | /** |
341 | * Save the state of the <tt>ArrayList</tt> instance to a stream (that |
342 | * is, serialize it). |
343 | * |
344 | * @serialData The length of the array backing the <tt>ArrayList</tt> |
345 | * instance is emitted (int), followed by all of its elements |
346 | * (each an <tt>Object</tt>) in the proper order. |
347 | */ |
348 | private void writeObject(java.io.ObjectOutputStream s) |
349 | throws java.io.IOException{ |
350 | // Write out element count, and any hidden stuff |
351 | int expectedModCount = modCount; |
352 | s.defaultWriteObject(); |
353 | |
354 | // Write out size as capacity for behavioural compatibility with clone() |
355 | s.writeInt(size); |
356 | |
357 | // Write out all elements in the proper order. |
358 | for (int i=0; i<size; i++) { |
359 | s.writeObject(elementData[i]); |
360 | } |
361 | |
362 | if (modCount != expectedModCount) { |
363 | throw new ConcurrentModificationException(); |
364 | } |
365 | } |
366 | |
367 | private void readObject(java.io.ObjectInputStream s) |
368 | throws java.io.IOException, ClassNotFoundException { |
369 | elementData = EMPTY_ELEMENTDATA; |
370 | |
371 | // Read in size, and any hidden stuff |
372 | s.defaultReadObject(); |
373 | |
374 | // Read in capacity |
375 | s.readInt(); // ignored |
376 | |
377 | if (size > 0) { |
378 | // be like clone(), allocate array based upon size not capacity |
379 | ensureCapacityInternal(size); |
380 | |
381 | Object[] a = elementData; |
382 | // Read in all elements in the proper order. |
383 | for (int i=0; i<size; i++) { |
384 | a[i] = s.readObject(); |
385 | } |
386 | } |
387 | } |
388 | |
389 | /** |
390 | * Returns a list iterator over the elements in this list (in proper |
391 | * sequence), starting at the specified position in the list. |
392 | * The specified index indicates the first element that would be |
393 | * returned by an initial call to {@link ListIterator#next next}. |
394 | * An initial call to {@link ListIterator#previous previous} would |
395 | * return the element with the specified index minus one. |
396 | * |
397 | * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>. |
398 | * |
399 | * @throws IndexOutOfBoundsException {@inheritDoc} |
400 | */ |
401 | public synchronized ListIterator<A> listIterator(int index) { |
402 | if (index < 0 || index > size) |
403 | throw new IndexOutOfBoundsException("Index: "+index); |
404 | return new ListItr(index); |
405 | } |
406 | |
407 | /** |
408 | * Returns a list iterator over the elements in this list (in proper |
409 | * sequence). |
410 | * |
411 | * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>. |
412 | * |
413 | * @see #listIterator(int) |
414 | */ |
415 | public ListIterator<A> listIterator() { |
416 | return new ListItr(0); |
417 | } |
418 | |
419 | /** |
420 | * Returns an iterator over the elements in this list in proper sequence. |
421 | * |
422 | * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>. |
423 | * |
424 | * @return an iterator over the elements in this list in proper sequence |
425 | */ |
426 | public Iterator<A> iterator() { |
427 | return concurrentlyIterateList(this); |
428 | } |
429 | |
430 | /** |
431 | * An optimized version of AbstractList.Itr |
432 | */ |
433 | private class Itr implements Iterator<A> { |
434 | int cursor; // index of next element to return |
435 | int lastRet = -1; // index of last element returned; -1 if no such |
436 | int expectedModCount = modCount; |
437 | |
438 | public boolean hasNext() { |
439 | return cursor != size; |
440 | } |
441 | |
442 | @SuppressWarnings("unchecked") |
443 | public A next() { |
444 | checkForComodification(); |
445 | int i = cursor; |
446 | if (i >= size) |
447 | throw new NoSuchElementException(); |
448 | Object[] elementData = SynchronizedArrayList.this.elementData; |
449 | if (i >= elementData.length) |
450 | throw new ConcurrentModificationException(); |
451 | cursor = i + 1; |
452 | return (A) elementData[lastRet = i]; |
453 | } |
454 | |
455 | public void remove() { |
456 | if (lastRet < 0) |
457 | throw new IllegalStateException(); |
458 | checkForComodification(); |
459 | |
460 | try { |
461 | SynchronizedArrayList.this.remove(lastRet); |
462 | cursor = lastRet; |
463 | lastRet = -1; |
464 | expectedModCount = modCount; |
465 | } catch (IndexOutOfBoundsException ex) { |
466 | throw new ConcurrentModificationException(); |
467 | } |
468 | } |
469 | |
470 | final void checkForComodification() { |
471 | if (modCount != expectedModCount) |
472 | throw new ConcurrentModificationException(); |
473 | } |
474 | } |
475 | |
476 | /** |
477 | * An optimized version of AbstractList.ListItr - TODO: replace with concurrent iterator or synchronize |
478 | */ |
479 | private class ListItr extends Itr implements ListIterator<A> { |
480 | ListItr(int index) { |
481 | super(); |
482 | cursor = index; |
483 | } |
484 | |
485 | public boolean hasPrevious() { |
486 | return cursor != 0; |
487 | } |
488 | |
489 | public int nextIndex() { |
490 | return cursor; |
491 | } |
492 | |
493 | public int previousIndex() { |
494 | return cursor - 1; |
495 | } |
496 | |
497 | @SuppressWarnings("unchecked") |
498 | public A previous() { |
499 | checkForComodification(); |
500 | int i = cursor - 1; |
501 | if (i < 0) |
502 | throw new NoSuchElementException(); |
503 | Object[] elementData = SynchronizedArrayList.this.elementData; |
504 | if (i >= elementData.length) |
505 | throw new ConcurrentModificationException(); |
506 | cursor = i; |
507 | return (A) elementData[lastRet = i]; |
508 | } |
509 | |
510 | public void set(A e) { |
511 | if (lastRet < 0) |
512 | throw new IllegalStateException(); |
513 | checkForComodification(); |
514 | |
515 | try { |
516 | SynchronizedArrayList.this.set(lastRet, e); |
517 | } catch (IndexOutOfBoundsException ex) { |
518 | throw new ConcurrentModificationException(); |
519 | } |
520 | } |
521 | |
522 | public void add(A e) { |
523 | checkForComodification(); |
524 | |
525 | try { |
526 | int i = cursor; |
527 | SynchronizedArrayList.this.add(i, e); |
528 | cursor = i + 1; |
529 | lastRet = -1; |
530 | expectedModCount = modCount; |
531 | } catch (IndexOutOfBoundsException ex) { |
532 | throw new ConcurrentModificationException(); |
533 | } |
534 | } |
535 | } |
536 | |
537 | public List<A> subList(int fromIndex, int toIndex) { |
538 | _subListRangeCheck(fromIndex, toIndex, size); |
539 | return new SubList(this, 0, fromIndex, toIndex); |
540 | } |
541 | |
542 | private class SubList extends SynchronizedArrayList_Base<A> implements RandomAccess { |
543 | private final SynchronizedArrayList_Base<A> parent; |
544 | private final int parentOffset; |
545 | private final int offset; |
546 | int size; |
547 | |
548 | SubList(SynchronizedArrayList_Base<A> parent, |
549 | int offset, int fromIndex, int toIndex) { |
550 | this.parent = parent; |
551 | this.parentOffset = fromIndex; |
552 | this.offset = offset + fromIndex; |
553 | this.size = toIndex - fromIndex; |
554 | this.modCount = SynchronizedArrayList.this.modCount; |
555 | } |
556 | |
557 | public A set(int index, A e) { synchronized(SynchronizedArrayList.this) { |
558 | rangeCheck(index); |
559 | checkForComodification(); |
560 | A oldValue = SynchronizedArrayList.this.elementData(offset + index); |
561 | SynchronizedArrayList.this.elementData[offset + index] = e; |
562 | return oldValue; |
563 | }} |
564 | |
565 | public A get(int index) { synchronized(SynchronizedArrayList.this) { |
566 | rangeCheck(index); |
567 | checkForComodification(); |
568 | return SynchronizedArrayList.this.elementData(offset + index); |
569 | }} |
570 | |
571 | public int size() { synchronized(SynchronizedArrayList.this) { |
572 | checkForComodification(); |
573 | return this.size; |
574 | }} |
575 | |
576 | public void add(int index, A e) { synchronized(SynchronizedArrayList.this) { |
577 | rangeCheckForAdd(index); |
578 | checkForComodification(); |
579 | parent.add(parentOffset + index, e); |
580 | this.modCount = parent.modCount(); |
581 | this.size++; |
582 | }} |
583 | |
584 | public A remove(int index) { synchronized(SynchronizedArrayList.this) { |
585 | rangeCheck(index); |
586 | checkForComodification(); |
587 | A result = parent.remove(parentOffset + index); |
588 | this.modCount = parent.modCount(); |
589 | this.size--; |
590 | return result; |
591 | }} |
592 | |
593 | public void removeRange(int fromIndex, int toIndex) { synchronized(SynchronizedArrayList.this) { |
594 | checkForComodification(); |
595 | parent.removeRange(parentOffset + fromIndex, |
596 | parentOffset + toIndex); |
597 | this.modCount = parent.modCount(); |
598 | this.size -= toIndex - fromIndex; |
599 | }} |
600 | |
601 | public boolean addAll(Collection<? extends A> c) { |
602 | return addAll(this.size, c); |
603 | } |
604 | |
605 | public boolean addAll(int index, Collection<? extends A> c) { synchronized(SynchronizedArrayList.this) { |
606 | rangeCheckForAdd(index); |
607 | int cSize = c.size(); |
608 | if (cSize==0) |
609 | return false; |
610 | |
611 | checkForComodification(); |
612 | parent.addAll(parentOffset + index, c); |
613 | this.modCount = parent.modCount(); |
614 | this.size += cSize; |
615 | return true; |
616 | }} |
617 | |
618 | public Iterator<A> iterator() { |
619 | return listIterator(); |
620 | } |
621 | |
622 | public ListIterator<A> listIterator(final int index) { synchronized(SynchronizedArrayList.this) { |
623 | checkForComodification(); |
624 | rangeCheckForAdd(index); |
625 | final int offset = this.offset; |
626 | |
627 | return new ListIterator<A>() { |
628 | int cursor = index; |
629 | int lastRet = -1; |
630 | int expectedModCount = SynchronizedArrayList.this.modCount; |
631 | |
632 | public boolean hasNext() { |
633 | return cursor != SubList.this.size; |
634 | } |
635 | |
636 | @SuppressWarnings("unchecked") |
637 | public A next() { |
638 | checkForComodification(); |
639 | int i = cursor; |
640 | if (i >= SubList.this.size) |
641 | throw new NoSuchElementException(); |
642 | Object[] elementData = SynchronizedArrayList.this.elementData; |
643 | if (offset + i >= elementData.length) |
644 | throw new ConcurrentModificationException(); |
645 | cursor = i + 1; |
646 | return (A) elementData[offset + (lastRet = i)]; |
647 | } |
648 | |
649 | public boolean hasPrevious() { |
650 | return cursor != 0; |
651 | } |
652 | |
653 | @SuppressWarnings("unchecked") |
654 | public A previous() { |
655 | checkForComodification(); |
656 | int i = cursor - 1; |
657 | if (i < 0) |
658 | throw new NoSuchElementException(); |
659 | Object[] elementData = SynchronizedArrayList.this.elementData; |
660 | if (offset + i >= elementData.length) |
661 | throw new ConcurrentModificationException(); |
662 | cursor = i; |
663 | return (A) elementData[offset + (lastRet = i)]; |
664 | } |
665 | |
666 | public int nextIndex() { |
667 | return cursor; |
668 | } |
669 | |
670 | public int previousIndex() { |
671 | return cursor - 1; |
672 | } |
673 | |
674 | public void remove() { |
675 | if (lastRet < 0) |
676 | throw new IllegalStateException(); |
677 | checkForComodification(); |
678 | |
679 | try { |
680 | SubList.this.remove(lastRet); |
681 | cursor = lastRet; |
682 | lastRet = -1; |
683 | expectedModCount = SynchronizedArrayList.this.modCount; |
684 | } catch (IndexOutOfBoundsException ex) { |
685 | throw new ConcurrentModificationException(); |
686 | } |
687 | } |
688 | |
689 | public void set(A e) { |
690 | if (lastRet < 0) |
691 | throw new IllegalStateException(); |
692 | checkForComodification(); |
693 | |
694 | try { |
695 | SynchronizedArrayList.this.set(offset + lastRet, e); |
696 | } catch (IndexOutOfBoundsException ex) { |
697 | throw new ConcurrentModificationException(); |
698 | } |
699 | } |
700 | |
701 | public void add(A e) { |
702 | checkForComodification(); |
703 | |
704 | try { |
705 | int i = cursor; |
706 | SubList.this.add(i, e); |
707 | cursor = i + 1; |
708 | lastRet = -1; |
709 | expectedModCount = SynchronizedArrayList.this.modCount; |
710 | } catch (IndexOutOfBoundsException ex) { |
711 | throw new ConcurrentModificationException(); |
712 | } |
713 | } |
714 | |
715 | final void checkForComodification() { |
716 | if (expectedModCount != SynchronizedArrayList.this.modCount) |
717 | throw new ConcurrentModificationException(); |
718 | } |
719 | }; |
720 | }} |
721 | |
722 | public List<A> subList(int fromIndex, int toIndex) { synchronized(SynchronizedArrayList.this) { |
723 | _subListRangeCheck(fromIndex, toIndex, size); |
724 | return new SubList(parent, offset, fromIndex, toIndex); |
725 | }} |
726 | |
727 | private void rangeCheck(int index) { |
728 | if (index < 0 || index >= this.size) |
729 | throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); |
730 | } |
731 | |
732 | private void rangeCheckForAdd(int index) { |
733 | if (index < 0 || index > this.size) |
734 | throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); |
735 | } |
736 | |
737 | private String outOfBoundsMsg(int index) { |
738 | return "Index: "+index+", Size: "+this.size; |
739 | } |
740 | |
741 | private void checkForComodification() { |
742 | if (SynchronizedArrayList.this.modCount != this.modCount) |
743 | throw new ConcurrentModificationException(); |
744 | } |
745 | } |
746 | |
747 | @Override |
748 | @SuppressWarnings("unchecked") |
749 | public synchronized void sort(Comparator<? super A> c) { |
750 | final int expectedModCount = modCount; |
751 | Arrays.sort((A[]) elementData, 0, size, c); |
752 | if (modCount != expectedModCount) { |
753 | throw new ConcurrentModificationException(); |
754 | } |
755 | modCount++; |
756 | } |
757 | } |
download show line numbers debug dex old transpilations
Travelled to 15 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt, ydilcnlqtmvn
No comments. add comment
Snippet ID: | #1012179 |
Snippet name: | SynchronizedArrayList - saves space over synchroList() |
Eternal ID of this version: | #1012179/15 |
Text MD5: | e53e5aa7bc42f942f2782236603360d6 |
Transpilation MD5: | 490abd71d95c9860471b0dd9ba03d3c7 |
Author: | stefan |
Category: | javax / collections |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2021-07-24 02:34:45 |
Source code size: | 24601 bytes / 757 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 604 / 2057 |
Version history: | 14 change(s) |
Referenced in: | [show references] |