1 |
|
/* |
2 |
< |
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. |
2 |
> |
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. |
3 |
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
|
* |
5 |
|
* This code is free software; you can redistribute it and/or modify it |
28 |
|
import java.util.function.Consumer; |
29 |
|
import java.util.function.Predicate; |
30 |
|
import java.util.function.UnaryOperator; |
31 |
+ |
import jdk.internal.misc.SharedSecrets; |
32 |
|
|
33 |
|
/** |
34 |
|
* Resizable-array implementation of the {@code List} interface. Implements |
314 |
|
* or -1 if there is no such index. |
315 |
|
*/ |
316 |
|
public int indexOf(Object o) { |
317 |
+ |
return indexOfRange(o, 0, size); |
318 |
+ |
} |
319 |
+ |
|
320 |
+ |
int indexOfRange(Object o, int start, int end) { |
321 |
+ |
Object[] es = elementData; |
322 |
|
if (o == null) { |
323 |
< |
for (int i = 0; i < size; i++) |
324 |
< |
if (elementData[i]==null) |
323 |
> |
for (int i = start; i < end; i++) { |
324 |
> |
if (es[i] == null) { |
325 |
|
return i; |
326 |
+ |
} |
327 |
+ |
} |
328 |
|
} else { |
329 |
< |
for (int i = 0; i < size; i++) |
330 |
< |
if (o.equals(elementData[i])) |
329 |
> |
for (int i = start; i < end; i++) { |
330 |
> |
if (o.equals(es[i])) { |
331 |
|
return i; |
332 |
+ |
} |
333 |
+ |
} |
334 |
|
} |
335 |
|
return -1; |
336 |
|
} |
343 |
|
* or -1 if there is no such index. |
344 |
|
*/ |
345 |
|
public int lastIndexOf(Object o) { |
346 |
+ |
return lastIndexOfRange(o, 0, size); |
347 |
+ |
} |
348 |
+ |
|
349 |
+ |
int lastIndexOfRange(Object o, int start, int end) { |
350 |
+ |
Object[] es = elementData; |
351 |
|
if (o == null) { |
352 |
< |
for (int i = size-1; i >= 0; i--) |
353 |
< |
if (elementData[i]==null) |
352 |
> |
for (int i = end - 1; i >= start; i--) { |
353 |
> |
if (es[i] == null) { |
354 |
|
return i; |
355 |
+ |
} |
356 |
+ |
} |
357 |
|
} else { |
358 |
< |
for (int i = size-1; i >= 0; i--) |
359 |
< |
if (o.equals(elementData[i])) |
358 |
> |
for (int i = end - 1; i >= start; i--) { |
359 |
> |
if (o.equals(es[i])) { |
360 |
|
return i; |
361 |
+ |
} |
362 |
+ |
} |
363 |
|
} |
364 |
|
return -1; |
365 |
|
} |
544 |
|
} |
545 |
|
|
546 |
|
/** |
547 |
+ |
* {@inheritDoc} |
548 |
+ |
*/ |
549 |
+ |
public boolean equals(Object o) { |
550 |
+ |
if (o == this) { |
551 |
+ |
return true; |
552 |
+ |
} |
553 |
+ |
|
554 |
+ |
if (!(o instanceof List)) { |
555 |
+ |
return false; |
556 |
+ |
} |
557 |
+ |
|
558 |
+ |
final int expectedModCount = modCount; |
559 |
+ |
// ArrayList can be subclassed and given arbitrary behavior, but we can |
560 |
+ |
// still deal with the common case where o is ArrayList precisely |
561 |
+ |
boolean equal = (o.getClass() == ArrayList.class) |
562 |
+ |
? equalsArrayList((ArrayList<?>) o) |
563 |
+ |
: equalsRange((List<?>) o, 0, size); |
564 |
+ |
|
565 |
+ |
checkForComodification(expectedModCount); |
566 |
+ |
return equal; |
567 |
+ |
} |
568 |
+ |
|
569 |
+ |
boolean equalsRange(List<?> other, int from, int to) { |
570 |
+ |
final Object[] es = elementData; |
571 |
+ |
if (to > es.length) { |
572 |
+ |
throw new ConcurrentModificationException(); |
573 |
+ |
} |
574 |
+ |
var oit = other.iterator(); |
575 |
+ |
for (; from < to; from++) { |
576 |
+ |
if (!oit.hasNext() || !Objects.equals(es[from], oit.next())) { |
577 |
+ |
return false; |
578 |
+ |
} |
579 |
+ |
} |
580 |
+ |
return !oit.hasNext(); |
581 |
+ |
} |
582 |
+ |
|
583 |
+ |
private boolean equalsArrayList(ArrayList<?> other) { |
584 |
+ |
final int otherModCount = other.modCount; |
585 |
+ |
final int s = size; |
586 |
+ |
boolean equal; |
587 |
+ |
if (equal = (s == other.size)) { |
588 |
+ |
final Object[] otherEs = other.elementData; |
589 |
+ |
final Object[] es = elementData; |
590 |
+ |
if (s > es.length || s > otherEs.length) { |
591 |
+ |
throw new ConcurrentModificationException(); |
592 |
+ |
} |
593 |
+ |
for (int i = 0; i < s; i++) { |
594 |
+ |
if (!Objects.equals(es[i], otherEs[i])) { |
595 |
+ |
equal = false; |
596 |
+ |
break; |
597 |
+ |
} |
598 |
+ |
} |
599 |
+ |
} |
600 |
+ |
other.checkForComodification(otherModCount); |
601 |
+ |
return equal; |
602 |
+ |
} |
603 |
+ |
|
604 |
+ |
private void checkForComodification(final int expectedModCount) { |
605 |
+ |
if (modCount != expectedModCount) { |
606 |
+ |
throw new ConcurrentModificationException(); |
607 |
+ |
} |
608 |
+ |
} |
609 |
+ |
|
610 |
+ |
/** |
611 |
+ |
* {@inheritDoc} |
612 |
+ |
*/ |
613 |
+ |
public int hashCode() { |
614 |
+ |
int expectedModCount = modCount; |
615 |
+ |
int hash = hashCodeRange(0, size); |
616 |
+ |
checkForComodification(expectedModCount); |
617 |
+ |
return hash; |
618 |
+ |
} |
619 |
+ |
|
620 |
+ |
int hashCodeRange(int from, int to) { |
621 |
+ |
final Object[] es = elementData; |
622 |
+ |
if (to > es.length) { |
623 |
+ |
throw new ConcurrentModificationException(); |
624 |
+ |
} |
625 |
+ |
int hashCode = 1; |
626 |
+ |
for (int i = from; i < to; i++) { |
627 |
+ |
Object e = es[i]; |
628 |
+ |
hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode()); |
629 |
+ |
} |
630 |
+ |
return hashCode; |
631 |
+ |
} |
632 |
+ |
|
633 |
+ |
/** |
634 |
|
* Removes the first occurrence of the specified element from this list, |
635 |
|
* if it is present. If the list does not contain the element, it is |
636 |
|
* unchanged. More formally, removes the element with the lowest index |
926 |
|
|
927 |
|
if (size > 0) { |
928 |
|
// like clone(), allocate array based upon size not capacity |
929 |
+ |
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size); |
930 |
|
Object[] elements = new Object[size]; |
931 |
|
|
932 |
|
// Read in all elements in the proper order. |
1227 |
|
return true; |
1228 |
|
} |
1229 |
|
|
1230 |
+ |
public void replaceAll(UnaryOperator<E> operator) { |
1231 |
+ |
root.replaceAllRange(operator, offset, offset + size); |
1232 |
+ |
} |
1233 |
+ |
|
1234 |
|
public boolean removeAll(Collection<?> c) { |
1235 |
|
return batchRemove(c, false); |
1236 |
|
} |
1258 |
|
return modified; |
1259 |
|
} |
1260 |
|
|
1261 |
+ |
public Object[] toArray() { |
1262 |
+ |
checkForComodification(); |
1263 |
+ |
return Arrays.copyOfRange(root.elementData, offset, offset + size); |
1264 |
+ |
} |
1265 |
+ |
|
1266 |
+ |
@SuppressWarnings("unchecked") |
1267 |
+ |
public <T> T[] toArray(T[] a) { |
1268 |
+ |
checkForComodification(); |
1269 |
+ |
if (a.length < size) |
1270 |
+ |
return (T[]) Arrays.copyOfRange( |
1271 |
+ |
root.elementData, offset, offset + size, a.getClass()); |
1272 |
+ |
System.arraycopy(root.elementData, offset, a, 0, size); |
1273 |
+ |
if (a.length > size) |
1274 |
+ |
a[size] = null; |
1275 |
+ |
return a; |
1276 |
+ |
} |
1277 |
+ |
|
1278 |
+ |
public boolean equals(Object o) { |
1279 |
+ |
if (o == this) { |
1280 |
+ |
return true; |
1281 |
+ |
} |
1282 |
+ |
|
1283 |
+ |
if (!(o instanceof List)) { |
1284 |
+ |
return false; |
1285 |
+ |
} |
1286 |
+ |
|
1287 |
+ |
boolean equal = root.equalsRange((List<?>)o, offset, offset + size); |
1288 |
+ |
checkForComodification(); |
1289 |
+ |
return equal; |
1290 |
+ |
} |
1291 |
+ |
|
1292 |
+ |
public int hashCode() { |
1293 |
+ |
int hash = root.hashCodeRange(offset, offset + size); |
1294 |
+ |
checkForComodification(); |
1295 |
+ |
return hash; |
1296 |
+ |
} |
1297 |
+ |
|
1298 |
+ |
public int indexOf(Object o) { |
1299 |
+ |
int index = root.indexOfRange(o, offset, offset + size); |
1300 |
+ |
checkForComodification(); |
1301 |
+ |
return index >= 0 ? index - offset : -1; |
1302 |
+ |
} |
1303 |
+ |
|
1304 |
+ |
public int lastIndexOf(Object o) { |
1305 |
+ |
int index = root.lastIndexOfRange(o, offset, offset + size); |
1306 |
+ |
checkForComodification(); |
1307 |
+ |
return index >= 0 ? index - offset : -1; |
1308 |
+ |
} |
1309 |
+ |
|
1310 |
+ |
public boolean contains(Object o) { |
1311 |
+ |
return indexOf(o) >= 0; |
1312 |
+ |
} |
1313 |
+ |
|
1314 |
|
public Iterator<E> iterator() { |
1315 |
|
return listIterator(); |
1316 |
|
} |
1718 |
|
setBit(deathRow, i - beg); |
1719 |
|
if (modCount != expectedModCount) |
1720 |
|
throw new ConcurrentModificationException(); |
1557 |
– |
expectedModCount++; |
1721 |
|
modCount++; |
1722 |
|
int w = beg; |
1723 |
|
for (i = beg; i < end; i++) |
1736 |
|
|
1737 |
|
@Override |
1738 |
|
public void replaceAll(UnaryOperator<E> operator) { |
1739 |
+ |
replaceAllRange(operator, 0, size); |
1740 |
+ |
} |
1741 |
+ |
|
1742 |
+ |
private void replaceAllRange(UnaryOperator<E> operator, int i, int end) { |
1743 |
|
Objects.requireNonNull(operator); |
1744 |
|
final int expectedModCount = modCount; |
1745 |
|
final Object[] es = elementData; |
1746 |
< |
final int size = this.size; |
1580 |
< |
for (int i = 0; modCount == expectedModCount && i < size; i++) |
1746 |
> |
for (; modCount == expectedModCount && i < end; i++) |
1747 |
|
es[i] = operator.apply(elementAt(es, i)); |
1748 |
|
if (modCount != expectedModCount) |
1749 |
|
throw new ConcurrentModificationException(); |
1584 |
– |
modCount++; |
1750 |
|
// checkInvariants(); |
1751 |
|
} |
1752 |
|
|