1 package java.util; 2 3 import sun.misc.SharedSecrets; 4 5 import java.util.function.Consumer; 6 import java.util.function.Predicate; 7 import java.util.function.UnaryOperator; 8 9 10 /** 11 * 概述: 12 * List接口可调整大小的数组实现。实现所有可选的List操作,并允许所有元素,包括null,元素可重复。 13 * 除了列表接口外,该类提供了一种方法来操作该数组的大小来存储该列表中的数组的大小。 14 * 时间复杂度: 15 * 方法size、isEmpty、get、set、iterator和listIterator的调用是常数时间的。 16 * 添加删除的时间复杂度为O(N)。其他所有操作也都是线性时间复杂度。 17 * 容量: 18 * 每个ArrayList都有容量,容量大小至少为List元素的长度,默认初始化为10。 19 * 容量可以自动增长。 20 * 如果提前知道数组元素较多,可以在添加元素前通过调用ensureCapacity()方法提前增加容量以减小后期容量自动增长的开销。 21 * 也可以通过带初始容量的构造器初始化这个容量。 22 * 线程不安全: 23 * ArrayList不是线程安全的。 24 * 如果需要应用到多线程中,需要在外部做同步 25 * modCount: 26 * 定义在AbstractList中:protected transient int modCount = 0; 27 * 已从结构上修改此列表的次数。从结构上修改是指更改列表的大小,或者打乱列表,从而使正在进行的迭代产生错误的结果。 28 * 此字段由iterator和listiterator方法返回的迭代器和列表迭代器实现使用。 29 * 如果意外更改了此字段中的值,则迭代器(或列表迭代器)将抛出concurrentmodificationexception来响应next、remove、previous、set或add操作。 30 * 在迭代期间面临并发修改时,它提供了快速失败 行为,而不是非确定性行为。 31 * 子类是否使用此字段是可选的。 32 * 如果子类希望提供快速失败迭代器(和列表迭代器),则它只需在其 add(int,e)和remove(int)方法(以及它所重写的、导致列表结构上修改的任何其他方法)中增加此字段。 33 * 对add(int, e)或remove(int)的单个调用向此字段添加的数量不得超过 1,否则迭代器(和列表迭代器)将抛出虚假的 concurrentmodificationexceptions。 34 * 如果某个实现不希望提供快速失败迭代器,则可以忽略此字段。 35 * transient: 36 * 默认情况下,对象的所有成员变量都将被持久化.在某些情况下,如果你想避免持久化对象的一些成员变量,你可以使用transient关键字来标记他们,transient也是java中的保留字(JDK 1.8) 37 */ 38 39 public class ArrayList912 * Similar idioms may be constructed for {@link #indexOf(Object)} and 913 * {@link #lastIndexOf(Object)}, and all of the algorithms in the 914 * {@link Collections} class can be applied to a subList. 915 *extends AbstractList 40 implements List , RandomAccess, Cloneable, java.io.Serializable { 41 private static final long serialVersionUID = 8683452581122892189L; 42 43 /** 44 * 默认容量 45 */ 46 private static final int DEFAULT_CAPACITY = 10; 47 48 /** 49 * 空的对象数组 50 */ 51 private static final Object[] EMPTY_ELEMENTDATA = {}; 52 53 /** 54 * 默认的空数组 55 * 无参构造函数创建的数组 56 */ 57 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; 58 59 /** 60 * 存放数据的数组的缓存变量,不可序列化 61 */ 62 transient Object[] elementData; 63 64 /** 65 * 元素数量 66 * 67 * @serial 68 */ 69 private int size; 70 71 /** 72 * 带有容量initialCapacity的构造方法 73 * 74 * @param 初始容量列表的初始容量 75 * @throws IllegalArgumentException 如果指定容量为负 76 */ 77 public ArrayList(int initialCapacity) { 78 // 如果初始化时ArrayList大小大于0 79 if (initialCapacity > 0) { 80 // new一个该大小的object数组赋给elementData 81 this.elementData = new Object[initialCapacity]; 82 } else if (initialCapacity == 0) {// 如果大小为0 83 // 将空数组赋给elementData 84 this.elementData = EMPTY_ELEMENTDATA; 85 } else {// 小于0 86 // 则抛出IllegalArgumentException异常 87 throw new IllegalArgumentException("Illegal Capacity: " + 88 initialCapacity); 89 } 90 } 91 92 /** 93 * 不带参数的构造方法 94 */ 95 public ArrayList() { 96 // 直接将空数组赋给elementData 97 this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; 98 } 99 100 /** 101 * 带参数Collection的构造方法 102 * 103 * @param c 其元素将被放入此列表中的集合 104 * @throws NullPointerException 如果指定的集合是空的 105 */ 106 public ArrayList(Collection extends E> c) { 107 elementData = c.toArray(); 108 if ((size = elementData.length) != 0) { 109 // c.toarray可能(错误地)不返回对象[](见JAVA BUG编号6260652) 110 if (elementData.getClass() != Object[].class) 111 elementData = Arrays.copyOf(elementData, size, Object[].class); 112 } else { 113 // 使用空数组 114 this.elementData = EMPTY_ELEMENTDATA; 115 } 116 } 117 118 /** 119 * 因为容量常常会大于实际元素的数量。内存紧张时,可以调用该方法删除预留的位置,调整容量为元素实际数量。 120 * 如果确定不会再有元素添加进来时也可以调用该方法来节约空间 121 */ 122 public void trimToSize() { 123 modCount++; 124 // 如果size小于length 125 if (size < elementData.length) { 126 // 重新将elementData设置大小为size 127 elementData = (size == 0) 128 ? EMPTY_ELEMENTDATA 129 : Arrays.copyOf(elementData, size); 130 } 131 } 132 133 /** 134 * 使用指定参数设置数组容量 135 * 136 * @param minCapacity 所需的最小容量 137 */ 138 public void ensureCapacity(int minCapacity) { 139 //如果数组为空,容量预取0,否则去默认值(10) 140 int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) 141 // any size if not default element table 142 ? 0 143 // larger than default for default empty table. It's already 144 // supposed to be at default size. 145 : DEFAULT_CAPACITY; 146 //若参数大于预设的容量,在使用该参数进一步设置数组容量 147 if (minCapacity > minExpand) { 148 ensureExplicitCapacity(minCapacity); 149 } 150 } 151 152 private static int calculateCapacity(Object[] elementData, int minCapacity) { 153 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { 154 return Math.max(DEFAULT_CAPACITY, minCapacity); 155 } 156 return minCapacity; 157 } 158 159 /** 160 * 得到最小扩容量 161 * 162 * @param minCapacity 163 */ 164 private void ensureCapacityInternal(int minCapacity) { 165 ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); 166 } 167 168 /** 169 * 判断是否需要扩容 170 * 171 * @param minCapacity 172 */ 173 private void ensureExplicitCapacity(int minCapacity) { 174 modCount++; 175 176 // 如果最小需要空间比elementData的内存空间要大,则需要扩容 177 if (minCapacity - elementData.length > 0) 178 grow(minCapacity); 179 } 180 181 /** 182 * 数组的最大容量,可能会导致内存溢出(VM内存限制) 183 */ 184 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; 185 186 /** 187 * 扩容,以确保它可以至少持有由参数指定的元素的数目 188 * 189 * @param minCapacity 所需的最小容量 190 */ 191 private void grow(int minCapacity) { 192 // 获取到ArrayList中elementData数组的内存空间长度 193 int oldCapacity = elementData.length; 194 // 扩容至原来的1.5倍 195 int newCapacity = oldCapacity + (oldCapacity >> 1); 196 // 再判断一下新数组的容量够不够,够了就直接使用这个长度创建新数组, 197 // 不够就将数组长度设置为需要的长度 198 if (newCapacity - minCapacity < 0) 199 newCapacity = minCapacity; 200 //若预设值大于默认的最大值检查是否溢出 201 if (newCapacity - MAX_ARRAY_SIZE > 0) 202 newCapacity = hugeCapacity(minCapacity); 203 // 调用Arrays.copyOf方法将elementData数组指向新的内存空间时newCapacity的连续空间 204 // 并将elementData的数据复制到新的内存空间 205 elementData = Arrays.copyOf(elementData, newCapacity); 206 } 207 208 /** 209 * 检查是否溢出,若没有溢出,返回最大整数值(java中的int为4字节,所以最大为0x7fffffff)或默认最大值 210 * 211 * @param minCapacity 212 * @return 213 */ 214 private static int hugeCapacity(int minCapacity) { 215 if (minCapacity < 0) //溢出 216 throw new OutOfMemoryError(); 217 return (minCapacity > MAX_ARRAY_SIZE) ? 218 Integer.MAX_VALUE : 219 MAX_ARRAY_SIZE; 220 } 221 222 /** 223 * 返回ArrayList的大小 224 * 225 * @return ArrayList中的元素数量 226 */ 227 public int size() { 228 return size; 229 } 230 231 /** 232 * 返回是否为空 233 * 234 * @return true 如果ArrayList中无元素 235 */ 236 public boolean isEmpty() { 237 return size == 0; 238 } 239 240 /** 241 * 是否包含一个数 返回bool 242 * 243 * @param o 检测o是否为ArrayList中元素 244 * @return true 如果ArrayList中包含o元素 245 */ 246 public boolean contains(Object o) { 247 return indexOf(o) >= 0; 248 } 249 250 251 /** 252 * 返回一个值在数组首次出现的位置,会根据是否为null使用不同方式判断。不存在就返回-1。时间复杂度为O(N) 253 * 254 * @param o 255 * @return 256 */ 257 public int indexOf(Object o) { 258 if (o == null) { 259 for (int i = 0; i < size; i++) 260 if (elementData[i] == null) 261 return i; 262 } else { 263 for (int i = 0; i < size; i++) 264 if (o.equals(elementData[i])) 265 return i; 266 } 267 return -1; 268 } 269 270 /** 271 * 返回一个值在数组最后一次出现的位置,会根据是否为null使用不同方式判断。不存在就返回-1。时间复杂度为O(N) 272 * 273 * @param o 274 * @return 275 */ 276 public int lastIndexOf(Object o) { 277 if (o == null) { 278 for (int i = size - 1; i >= 0; i--) 279 if (elementData[i] == null) 280 return i; 281 } else { 282 for (int i = size - 1; i >= 0; i--) 283 if (o.equals(elementData[i])) 284 return i; 285 } 286 return -1; 287 } 288 289 /** 290 * 返回副本,元素本身没有被复制,复制过程数组发生改变会抛出异常 291 * 292 * @return v ArrayList副本 293 */ 294 public Object clone() { 295 try { 296 // 调用父类(翻看源码可见是Object类)的clone方法得到一个ArrayList副本 297 ArrayList> v = (ArrayList>) super.clone(); 298 // 调用Arrays类的copyOf,将ArrayList的elementData数组赋值给副本的elementData数组 299 v.elementData = Arrays.copyOf(elementData, size); 300 v.modCount = 0; 301 // 返回副本v 302 return v; 303 } catch (CloneNotSupportedException e) { 304 // this shouldn't happen, since we are Cloneable 305 throw new InternalError(e); 306 } 307 } 308 309 /** 310 * 转换为Object数组,使用Arrays.copyOf()方法 311 * 312 * @return 一个数组包含所有列表中的元素, 且顺序正确 313 */ 314 public Object[] toArray() { 315 return Arrays.copyOf(elementData, size); 316 } 317 318 /** 319 * 将ArrayList里面的元素赋值到一个数组中去 320 * 如果a的长度小于ArrayList的长度,直接调用Arrays类的copyOf,返回一个比a数组长度要大的新数组,里面元素就是ArrayList里面的元素; 321 * 如果a的长度比ArrayList的长度大,那么就调用System.arraycopy,将ArrayList的elementData数组赋值到a数组,然后把a数组的size位置赋值为空。 322 * 323 * @param a 如果它的长度大的话,列表元素将存储在这个数组中; 否则,将为此分配一个相同运行时类型的新数组。 324 * @return 一个包含ArrayList元素的数组 325 * @throws ArrayStoreException 将与数组类型不兼容的值赋值给数组元素时抛出的异常 326 * @throws NullPointerException 数组为空 327 */ 328 @SuppressWarnings("unchecked") 329 public T[] toArray(T[] a) { 330 if (a.length < size) 331 // 创建一个新的a的运行时类型数组,内容不变 332 return (T[]) Arrays.copyOf(elementData, size, a.getClass()); 333 System.arraycopy(elementData, 0, a, 0, size); 334 if (a.length > size) 335 a[size] = null; 336 return a; 337 } 338 339 340 /** 341 * 返回指定位置的值,因为是数组,所以速度特别快 342 * 343 * @param index 344 * @return 345 */ 346 @SuppressWarnings("unchecked") 347 E elementData(int index) { 348 return (E) elementData[index]; 349 } 350 351 /** 352 * 返回指定位置的值,但是会先检查这个位置数否超出数组长度 353 * 354 * @param index 要返回的元素的索引 355 * @return ArrayList中指定位置的元素 356 * @throws IndexOutOfBoundsException {@inheritDoc} 357 */ 358 public E get(int index) { 359 // 检查是否越界 360 rangeCheck(index); 361 // 返回ArrayList的elementData数组index位置的元素 362 return elementData(index); 363 } 364 365 /** 366 * 设置指定位置为一个新值,并返回之前的值,会检查这个位置是否超出数组长度 367 * 368 * @param index 要替换的元素的索引 369 * @param element 要存储在指定位置的元素 370 * @return 之前在指定位置的元素 371 * @throws IndexOutOfBoundsException {@inheritDoc} 372 */ 373 public E set(int index, E element) { 374 // 检查是否越界 375 rangeCheck(index); 376 // 调用elementData(index)获取到当前位置的值 377 E oldValue = elementData(index); 378 // 将element赋值到ArrayList的elementData数组的第index位置 379 elementData[index] = element; 380 return oldValue; 381 } 382 383 /** 384 * 添加一个值,首先会确保容量 385 * 386 * @param e 要添加到此列表中的元素 387 * @return true (as specified by {@link Collection#add}) 388 */ 389 public boolean add(E e) { 390 // 扩容 391 ensureCapacityInternal(size + 1); // Increments modCount!! 392 // 将e赋值给elementData的size+1的位置 393 elementData[size++] = e; 394 return true; 395 } 396 397 /** 398 * 在ArrayList的index位置,添加元素element,会检查添加的位置和容量 399 * 400 * @param index 指定元素将被插入的索引 401 * @param element 要插入的元素 402 * @throws IndexOutOfBoundsException {@inheritDoc} 403 */ 404 public void add(int index, E element) { 405 // 判断index是否越界 406 rangeCheckForAdd(index); 407 // 扩容 408 ensureCapacityInternal(size + 1); // Increments modCount!! 409 //public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 410 //src:源数组; srcPos:源数组要复制的起始位置; dest:目的数组; destPos:目的数组放置的起始位置; length:复制的长度 411 // 将elementData从index位置开始,复制到elementData的index+1开始的连续空间 412 System.arraycopy(elementData, index, elementData, index + 1, 413 size - index); 414 // 在elementData的index位置赋值element 415 elementData[index] = element; 416 // ArrayList的大小加一 417 size++; 418 } 419 420 /** 421 * 在ArrayList的移除index位置的元素,会检查添加的位置,返回之前的值 422 * 423 * @param index 要删除的元素的索引 424 * @return 从ArrayList中删除的元素 425 * @throws IndexOutOfBoundsException {@inheritDoc} 426 */ 427 public E remove(int index) { 428 // 判断是否越界 429 rangeCheck(index); 430 431 modCount++; 432 // 读取旧值 433 E oldValue = elementData(index); 434 // 获取index位置开始到最后一个位置的个数 435 int numMoved = size - index - 1; 436 if (numMoved > 0) 437 // 将elementData数组index+1位置开始拷贝到elementData从index开始的空间 438 System.arraycopy(elementData, index + 1, elementData, index, 439 numMoved); 440 // 使size-1 ,设置elementData的size位置为空,让GC来清理内存空间 441 elementData[--size] = null; //便于垃圾回收器回收 442 443 return oldValue; 444 } 445 446 /** 447 * 在ArrayList的移除对象为O的元素,跟indexOf方法思想基本一致 448 * 449 * @param o 要从该列表中删除的元素(如果存在) 450 * @return true 如果这个列表包含指定的元素 451 */ 452 public boolean remove(Object o) { 453 if (o == null) { 454 for (int index = 0; index < size; index++) 455 if (elementData[index] == null) { 456 fastRemove(index); 457 return true; 458 } 459 } else { 460 for (int index = 0; index < size; index++) 461 if (o.equals(elementData[index])) { 462 fastRemove(index); 463 return true; 464 } 465 } 466 return false; 467 } 468 469 470 /** 471 * 快速删除指定位置的值,之所以叫快速,应该是不需要检查和返回值,因为只内部使用 472 * 473 * @param index 474 */ 475 private void fastRemove(int index) { 476 modCount++; 477 int numMoved = size - index - 1; 478 if (numMoved > 0) 479 System.arraycopy(elementData, index + 1, elementData, index, 480 numMoved); 481 // 使size-1 ,设置elementData的size位置为空,让GC来清理内存空间 482 elementData[--size] = null; //便于垃圾回收器回收 483 } 484 485 /** 486 * 清空数组,把每一个值设为null,方便垃圾回收(不同于reset,数组默认大小有改变的话不会重置) 487 */ 488 public void clear() { 489 modCount++; 490 491 //便于垃圾回收器回收 492 for (int i = 0; i < size; i++) 493 elementData[i] = null; 494 //把size设置为0,以便我们不会浏览到null值的内存空间 495 size = 0; 496 } 497 498 /** 499 * 添加一个集合的元素到末端,若要添加的集合为空返回false 500 * 501 * @param c 包含要添加到此列表中的元素的集合 502 * @return true 如果该列表因添加而改变 503 * @throws NullPointerException 如果指定的集合是空的 504 */ 505 public boolean addAll(Collection extends E> c) { 506 // 将c转换为数组a 507 Object[] a = c.toArray(); 508 // 获取a占的内存空间长度赋值给numNew 509 int numNew = a.length; 510 // 扩容至size + numNew 511 ensureCapacityInternal(size + numNew); // Increments modCount 512 // 将a的第0位开始拷贝至elementData的size位开始,拷贝长度为numNew 513 System.arraycopy(a, 0, elementData, size, numNew); 514 // 将size增加numNew 515 size += numNew; 516 // 如果c为空,返回false,c不为空,返回true 517 return numNew != 0; 518 } 519 520 /** 521 * 从第index位开始,将c全部拷贝到ArrayList,若要添加的集合为空返回false 522 * 523 * @param index 在哪个索引处插入指定集合中的第一个元素 524 * @param c 包含要添加到此列表中的元素的集合 525 * @return true 如果该列表因添加而改变 526 * @throws IndexOutOfBoundsException {@inheritDoc} 527 * @throws NullPointerException 如果指定的集合是空的 528 */ 529 public boolean addAll(int index, Collection extends E> c) { 530 // 判断index大于size或者是小于0,如果是,则抛出IndexOutOfBoundsException异常 531 rangeCheckForAdd(index); 532 // 将c转换为数组a 533 Object[] a = c.toArray(); 534 int numNew = a.length; 535 // 扩容至size + numNew 536 ensureCapacityInternal(size + numNew); // Increments modCount 537 // 获取需要添加的个数 538 int numMoved = size - index; 539 if (numMoved > 0) 540 System.arraycopy(elementData, index, elementData, index + numNew, 541 numMoved); 542 543 System.arraycopy(a, 0, elementData, index, numNew); 544 size += numNew; 545 return numNew != 0; 546 } 547 548 /** 549 * 删除指定范围元素。参数为开始删的位置和结束位置 550 * 551 * @throws IndexOutOfBoundsException if {@code fromIndex} or 552 * {@code toIndex} is out of range 553 * ({@code fromIndex < 0 || 554 * fromIndex >= size() || 555 * toIndex > size() || 556 * toIndex < fromIndex}) 557 */ 558 protected void removeRange(int fromIndex, int toIndex) { 559 modCount++; 560 int numMoved = size - toIndex;//后段保留的长度 561 System.arraycopy(elementData, toIndex, elementData, fromIndex, 562 numMoved); 563 564 //便于垃圾回收期回收 565 int newSize = size - (toIndex - fromIndex); 566 for (int i = newSize; i < size; i++) { 567 elementData[i] = null; 568 } 569 size = newSize; 570 } 571 572 /** 573 * 检查index是否超出数组长度 用于添加元素时 574 */ 575 private void rangeCheck(int index) { 576 // 如果下标超过ArrayList的数组长度 577 if (index >= size) 578 throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); 579 } 580 581 /** 582 * 检查是否溢出 583 */ 584 private void rangeCheckForAdd(int index) { 585 if (index > size || index < 0) 586 throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); 587 } 588 589 /** 590 * 抛出的异常的详情 591 */ 592 private String outOfBoundsMsg(int index) { 593 return "Index: " + index + ", Size: " + size; 594 } 595 596 /** 597 * ArrayList移除集合c中的所有元素 598 * 599 * @param c 包含要从此列表中移除的元素的集合 600 * @return {@code true} 如果该列表因移除而改变 601 * @throws ClassCastException if the class of an element of this list 602 * is incompatible with the specified collection 603 * (optional) 604 * @throws NullPointerException if this list contains a null element and the 605 * specified collection does not permit null elements 606 * (optional), 607 * or if the specified collection is null 608 * @see Collection#contains(Object) 609 */ 610 public boolean removeAll(Collection> c) { 611 // 如果c为空,则抛出空指针异常 612 Objects.requireNonNull(c); 613 // 调用batchRemove移除c中的元素 614 return batchRemove(c, false); 615 } 616 617 /** 618 * 仅保留指定集合c中的元素 619 * 620 * @param c collection containing elements to be retained in this list 621 * @return {@code true} if this list changed as a result of the call 622 * @throws ClassCastException if the class of an element of this list 623 * is incompatible with the specified collection 624 * (optional) 625 * @throws NullPointerException if this list contains a null element and the 626 * specified collection does not permit null elements 627 * (optional), 628 * or if the specified collection is null 629 * @see Collection#contains(Object) 630 */ 631 public boolean retainAll(Collection> c) { 632 Objects.requireNonNull(c); 633 // 调用batchRemove保留c中的元素 634 return batchRemove(c, true); 635 } 636 637 /** 638 * 根据complement值,将ArrayList中包含c中元素的元素删除或者保留 639 * 640 * @param c 641 * @param complement true时从数组保留指定集合中元素的值,为false时从数组删除指定集合中元素的值。 642 * @return 数组中重复的元素都会被删除(而不是仅删除一次或几次),有任何删除操作都会返回true 643 */ 644 private boolean batchRemove(Collection> c, boolean complement) { 645 final Object[] elementData = this.elementData; 646 // 定义一个w,一个r,两个同时右移 647 int r = 0, w = 0; 648 boolean modified = false; 649 try { 650 // r先右移 651 for (; r < size; r++) 652 // 如果c中不包含elementData[r]这个元素 653 if (c.contains(elementData[r]) == complement) 654 // 则直接将r位置的元素赋值给w位置的元素,w自增 655 elementData[w++] = elementData[r]; 656 } finally { 657 // 防止抛出异常导致上面r的右移过程没完成 658 if (r != size) { 659 // 将r未右移完成的位置的元素赋值给w右边位置的元素 660 System.arraycopy(elementData, r, 661 elementData, w, 662 size - r); 663 // 修改w值增加size-r 664 w += size - r; 665 } 666 // 如果有被覆盖掉的元素,则将w后面的元素都赋值为null 667 if (w != size) { 668 // clear to let GC do its work 669 for (int i = w; i < size; i++) 670 elementData[i] = null; 671 modCount += size - w;//改变的次数 672 //新的大小为保留的元素的个数 673 size = w; 674 modified = true; 675 } 676 } 677 return modified; 678 } 679 680 /** 681 * 保存数组实例的状态到一个流(即序列化)。写入过程数组被更改会抛出异常 682 * 683 * @serialData The length of the array backing the ArrayList 684 * instance is emitted (int), followed by all of its elements 685 * (each an Object) in the proper order. 686 */ 687 private void writeObject(java.io.ObjectOutputStream s) 688 throws java.io.IOException { 689 // Write out element count, and any hidden stuff 690 int expectedModCount = modCount; 691 //执行默认的反序列化/序列化过程。将当前类的非静态和非瞬态字段写入此流 692 s.defaultWriteObject(); 693 694 // 写入大小 695 s.writeInt(size); 696 697 // 按顺序写入所有元素 698 for (int i = 0; i < size; i++) { 699 s.writeObject(elementData[i]); 700 } 701 702 if (modCount != expectedModCount) { 703 throw new ConcurrentModificationException(); 704 } 705 } 706 707 /** 708 * 从流中重构ArrayList实例(即反序列化)。 709 */ 710 private void readObject(java.io.ObjectInputStream s) 711 throws java.io.IOException, ClassNotFoundException { 712 elementData = EMPTY_ELEMENTDATA; 713 714 // 执行默认的序列化/反序列化过程 715 s.defaultReadObject(); 716 717 // 读入数组长度 718 s.readInt(); // ignored 719 720 if (size > 0) { 721 // 像clone()方法 ,但根据大小而不是容量分配数组 722 int capacity = calculateCapacity(elementData, size); 723 SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity); 724 ensureCapacityInternal(size); 725 726 Object[] a = elementData; 727 //读入所有元素 728 for (int i = 0; i < size; i++) { 729 a[i] = s.readObject(); 730 } 731 } 732 } 733 734 /** 735 * 返回一个从index开始的ListIterator对象 736 * 737 * @throws IndexOutOfBoundsException {@inheritDoc} 738 */ 739 public ListIterator listIterator(int index) { 740 if (index < 0 || index > size) 741 throw new IndexOutOfBoundsException("Index: " + index); 742 return new ListItr(index); 743 } 744 745 /** 746 * 返回一个ListIterator对象,ListItr为ArrayList的一个内部类,其实现了ListIterator 接口 747 * 748 * @see #listIterator(int) 749 */ 750 public ListIteratorlistIterator() { 751 return new ListItr(0); 752 } 753 754 /** 755 * 返回一个Iterator对象,Itr为ArrayList的一个内部类,其实现了Iterator 接口 756 * 757 * @return an iterator over the elements in this list in proper sequence 758 */ 759 public Iteratoriterator() { 760 return new Itr(); 761 } 762 763 /** 764 * 通用的迭代器实现 765 */ 766 private class Itr implements Iterator { 767 int cursor; //游标,下一个元素的索引,默认初始化为0 768 int lastRet = -1; //上次访问的元素的位置 769 int expectedModCount = modCount;//迭代过程不运行修改数组,否则就抛出异常 770 771 //是否还有下一个 772 public boolean hasNext() { 773 return cursor != size; 774 } 775 776 //下一个元素 777 @SuppressWarnings("unchecked") 778 public E next() { 779 checkForComodification();//检查数组是否被修改 780 int i = cursor; 781 if (i >= size) 782 throw new NoSuchElementException(); 783 Object[] elementData = ArrayList.this.elementData; 784 if (i >= elementData.length) 785 throw new ConcurrentModificationException(); 786 cursor = i + 1;//向后移动游标 787 return (E) elementData[lastRet = i];//设置访问的位置并返回这个值 788 } 789 790 //删除元素 791 public void remove() { 792 if (lastRet < 0) 793 throw new IllegalStateException(); 794 checkForComodification();//检查数组是否被修改 795 796 try { 797 ArrayList.this.remove(lastRet); 798 cursor = lastRet; 799 lastRet = -1; 800 expectedModCount = modCount; 801 } catch (IndexOutOfBoundsException ex) { 802 throw new ConcurrentModificationException(); 803 } 804 } 805 806 @Override 807 @SuppressWarnings("unchecked") 808 public void forEachRemaining(Consumer super E> consumer) { 809 Objects.requireNonNull(consumer); 810 final int size = ArrayList.this.size; 811 int i = cursor; 812 if (i >= size) { 813 return; 814 } 815 final Object[] elementData = ArrayList.this.elementData; 816 if (i >= elementData.length) { 817 throw new ConcurrentModificationException(); 818 } 819 while (i != size && modCount == expectedModCount) { 820 consumer.accept((E) elementData[i++]); 821 } 822 // update once at end of iteration to reduce heap write traffic 823 cursor = i; 824 lastRet = i - 1; 825 checkForComodification(); 826 } 827 828 //检查数组是否被修改 829 final void checkForComodification() { 830 if (modCount != expectedModCount) 831 throw new ConcurrentModificationException(); 832 } 833 } 834 835 /** 836 * ListIterator迭代器实现 837 */ 838 private class ListItr extends Itr implements ListIterator { 839 ListItr(int index) { 840 super(); 841 cursor = index; 842 } 843 844 public boolean hasPrevious() { 845 return cursor != 0; 846 } 847 848 public int nextIndex() { 849 return cursor; 850 } 851 852 public int previousIndex() { 853 return cursor - 1; 854 } 855 856 @SuppressWarnings("unchecked") 857 public E previous() { 858 checkForComodification(); 859 int i = cursor - 1; 860 if (i < 0) 861 throw new NoSuchElementException(); 862 Object[] elementData = ArrayList.this.elementData; 863 if (i >= elementData.length) 864 throw new ConcurrentModificationException(); 865 cursor = i; 866 return (E) elementData[lastRet = i]; 867 } 868 869 public void set(E e) { 870 if (lastRet < 0) 871 throw new IllegalStateException(); 872 checkForComodification(); 873 874 try { 875 ArrayList.this.set(lastRet, e); 876 } catch (IndexOutOfBoundsException ex) { 877 throw new ConcurrentModificationException(); 878 } 879 } 880 881 public void add(E e) { 882 checkForComodification(); 883 884 try { 885 int i = cursor; 886 ArrayList.this.add(i, e); 887 cursor = i + 1; 888 lastRet = -1; 889 expectedModCount = modCount; 890 } catch (IndexOutOfBoundsException ex) { 891 throw new ConcurrentModificationException(); 892 } 893 } 894 } 895 896 /** 897 * Returns a view of the portion of this list between the specified 898 * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. (If 899 * {@code fromIndex} and {@code toIndex} are equal, the returned list is 900 * empty.) The returned list is backed by this list, so non-structural 901 * changes in the returned list are reflected in this list, and vice-versa. 902 * The returned list supports all of the optional list operations. 903 * 904 *
This method eliminates the need for explicit range operations (of
905 * the sort that commonly exist for arrays). Any operation that expects 906 * a list can be used as a range operation by passing a subList view 907 * instead of a whole list. For example, the following idiom 908 * removes a range of elements from a list: 909 *910 * list.subList(from, to).clear(); 911 *
916 *
The semantics of the list returned by this method become undefined if
917 * the backing list (i.e., this list) is structurally modified in 918 * any way other than via the returned list. (Structural modifications are 919 * those that change the size of this list, or otherwise perturb it in such 920 * a fashion that iterations in progress may yield incorrect results.) 921 * 922 * @throws IndexOutOfBoundsException {@inheritDoc} 923 * @throws IllegalArgumentException {@inheritDoc} 924 */ 925 public List1207 *
The {
@code Spliterator} reports {@link Spliterator#SIZED}, 1208 * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}. 1209 * Overriding implementations should document the reporting of additional 1210 * characteristic values. 1211 * 1212 * @return a {@code Spliterator} over the elements in this list 1213 * @since 1.8 1214 */ 1215 @Override 1216 public Spliterator