• 知识脉络
      • arraylist底层是一个object的数组,优点是随机访问快,缺点是扩容和插入和删除元素,会进行元素拷贝性能查,不是线程安全
      • 创建Arraylist,不指定大小,arraylist第一次添加元素,会指定默认的容量大小为10
      • ArrayList的扩容机制主要有两点,一个是计算扩容的大小=原值+原值右移1(等价1.5倍),一个是底层通过System.arrycopy来拷贝元素和创建信数组,来最终实现空间的扩容
      • 核心方法大多通过system.arraycopy进行拷贝元素做到的,removelf方法中
      • 遍历通过内部类ltr遍历时会向后访问,Listltr遍历向前、向后均可访问,由于不是线程安全,通过modcout的检测,实现fail-fast机制
      • Vector通过synchronized关键字的ArrayList,线程安全,扩容是原来的2倍stack继承了vector,使用数组模仿栈的操作而已
      • fail-fast 机制,即快速失败机制,是java集合(Collection)中的一种错误检测机制。当使用迭代器时候,进行一定的改变,就有可能会发生fail-fast,即抛出ConcurrentModificationException异常。fail-fast机制并不保证在不同步的修改下一定会抛出异常,它只是尽最大努力去抛出,所以这种机制通常用来检测bug,在迭代删除值的时候,要使用iterator,remove()方法,通过checkForComodification方法来检查modCount 和expectedModCount,如果不一致则会报出concurrentmodifictionException,在高并发环境下,推荐使用CopyOnWriteArrayList,ConcurrentHashMap
    • 扩容源码:
    • 内部类
      • ArrayListSpliterator (分离器)
        1. Spliteratorjdk8新引入的,它与collectionstream api结合使用,可以并发处理数据,默认进行是进行二次分割,也可以进行自定义重写相关方法,
    1. private int index; //当前位置
    2. private int fence; //结束位置
    3. private int expectedModCount; //modecount
    4. //获取当前的位置
    5. private int getFence() {
    6. int hi;
    7. if ((hi = this.fence) < 0) { //防止负数出现,已经运行完毕
    8. this.expectedModCount = ArrayList.this.modCount;
    9. hi = this.fence = ArrayList.this.size;
    10. }
    11. return hi;
    12. }
    13. //尝试切割
    14. public ArrayList<E>.ArrayListSpliterator trySplit() {
    15. int hi = this.getFence();
    16. int lo = this.index;
    17. int mid = lo + hi >>> 1; 右运算符1,计算出中间的位置
    18. return lo >= mid ? null : ArrayList.this.new ArrayListSpliterator(lo, this.index = mid, this.expectedModCount);
    19. }
    20. //单次遍历,改变index只加1
    21. public boolean tryAdvance(Consumer<? super E> action) {
    22. if (action == null) {
    23. throw new NullPointerException();
    24. } else {
    25. int hi = this.getFence();
    26. int i = this.index;
    27. if (i < hi) {
    28. this.index = i + 1;
    29. E e = ArrayList.this.elementData[i];
    30. action.accept(e);
    31. if (ArrayList.this.modCount != this.expectedModCount) {
    32. throw new ConcurrentModificationException();
    33. } else {
    34. return true;
    35. }
    36. } else {
    37. return false;
    38. }
    39. }
    40. }
    41. //整体遍历
    42. public void forEachRemaining(Consumer<? super E> action) {
    43. if (action == null) {
    44. throw new NullPointerException();
    45. } else {
    46. Object[] a;
    47. if ((a = ArrayList.this.elementData) != null) {
    48. int hi;
    49. int mc;
    50. if ((hi = this.fence) < 0) {
    51. mc = ArrayList.this.modCount;
    52. hi = ArrayList.this.size;
    53. } else {
    54. mc = this.expectedModCount;
    55. }
    56. int i;
    57. if ((i = this.index) >= 0 && (this.index = hi) <= a.length) {
    58. while(i < hi) {
    59. E e = a[i];
    60. action.accept(e);
    61. ++i;
    62. }
    63. if (ArrayList.this.modCount == mc) {
    64. return;
    65. }
    66. }
    67. }
    68. throw new ConcurrentModificationException();
    69. }
    70. }
    • SubList
      1. arrayList.sublist返回的是父集合的一部分视图,是视图、是视图、是视图,重要的事说3遍,无论改变那个集合,另一个都会随动。
    1. public List<E> subList(int fromIndex, int toIndex) {
    2. subListRangeCheck(fromIndex, toIndex, this.size);
    3. return new ArrayList.SubList(this, fromIndex, toIndex);//生成一个子类SubList
    4. }
    5. //set,get,size,add,remove 都会检测modcount,fast-fail机制
    6. private void checkForComodification() {
    7. if (this.root.modCount != this.modCount) {
    8. throw new ConcurrentModificationException();
    9. }
    10. }
    11. public E set(int index, E element) {
    12. Objects.checkIndex(index, this.size);
    13. this.checkForComodification();
    14. E oldValue = this.root.elementData(this.offset + index);
    15. this.root.elementData[this.offset + index] = element;
    16. return oldValue;
    17. }
    18. public E get(int index) {
    19. Objects.checkIndex(index, this.size);
    20. this.checkForComodification();
    21. return this.root.elementData(this.offset + index);
    22. }
    23. public int size() {
    24. this.checkForComodification();
    25. return this.size;
    26. }
    27. public void add(int index, E element) {
    28. this.rangeCheckForAdd(index);
    29. this.checkForComodification();
    30. this.root.add(this.offset + index, element);
    31. this.updateSizeAndModCount(1);
    32. }
    33. public E remove(int index) {
    34. Objects.checkIndex(index, this.size);
    35. this.checkForComodification();
    36. E result = this.root.remove(this.offset + index);
    37. this.updateSizeAndModCount(-1);
    38. return result;
    39. }
    • ltr
      1. arrylist.iterator 触发内部类ltr
    1. public Iterator<E> iterator() {
    2. return new ArrayList.Itr();
    3. }
    • listltr
    1. public ListIterator<E> listIterator(int index) {
    2. this.rangeCheckForAdd(index);
    3. return new ArrayList.ListItr(index);
    4. }
    5. public ListIterator<E> listIterator() {
    6. return new ArrayList.ListItr(0);
    7. }