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