- 知识脉络
- 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 (分离器)
Spliterator是jdk8新引入的,它与collection,stream api结合使用,可以并发处理数据,默认进行是进行二次分割,也可以进行自定义重写相关方法,
private int index; //当前位置 private int fence; //结束位置 private int expectedModCount; //modecount//获取当前的位置private int getFence() { int hi; if ((hi = this.fence) < 0) { //防止负数出现,已经运行完毕 this.expectedModCount = ArrayList.this.modCount; hi = this.fence = ArrayList.this.size; } return hi; }//尝试切割 public ArrayList<E>.ArrayListSpliterator trySplit() { int hi = this.getFence(); int lo = this.index; int mid = lo + hi >>> 1; 右运算符1,计算出中间的位置 return lo >= mid ? null : ArrayList.this.new ArrayListSpliterator(lo, this.index = mid, this.expectedModCount); } //单次遍历,改变index只加1 public boolean tryAdvance(Consumer<? super E> action) { if (action == null) { throw new NullPointerException(); } else { int hi = this.getFence(); int i = this.index; if (i < hi) { this.index = i + 1; E e = ArrayList.this.elementData[i]; action.accept(e); if (ArrayList.this.modCount != this.expectedModCount) { throw new ConcurrentModificationException(); } else { return true; } } else { return false; } } } //整体遍历 public void forEachRemaining(Consumer<? super E> action) { if (action == null) { throw new NullPointerException(); } else { Object[] a; if ((a = ArrayList.this.elementData) != null) { int hi; int mc; if ((hi = this.fence) < 0) { mc = ArrayList.this.modCount; hi = ArrayList.this.size; } else { mc = this.expectedModCount; } int i; if ((i = this.index) >= 0 && (this.index = hi) <= a.length) { while(i < hi) { E e = a[i]; action.accept(e); ++i; } if (ArrayList.this.modCount == mc) { return; } } } throw new ConcurrentModificationException(); } }
- SubList
arrayList.sublist返回的是父集合的一部分视图,是视图、是视图、是视图,重要的事说3遍,无论改变那个集合,另一个都会随动。
public List<E> subList(int fromIndex, int toIndex) { subListRangeCheck(fromIndex, toIndex, this.size); return new ArrayList.SubList(this, fromIndex, toIndex);//生成一个子类SubList } //set,get,size,add,remove 都会检测modcount,fast-fail机制 private void checkForComodification() { if (this.root.modCount != this.modCount) { throw new ConcurrentModificationException(); } } public E set(int index, E element) { Objects.checkIndex(index, this.size); this.checkForComodification(); E oldValue = this.root.elementData(this.offset + index); this.root.elementData[this.offset + index] = element; return oldValue; } public E get(int index) { Objects.checkIndex(index, this.size); this.checkForComodification(); return this.root.elementData(this.offset + index); } public int size() { this.checkForComodification(); return this.size; } public void add(int index, E element) { this.rangeCheckForAdd(index); this.checkForComodification(); this.root.add(this.offset + index, element); this.updateSizeAndModCount(1); } public E remove(int index) { Objects.checkIndex(index, this.size); this.checkForComodification(); E result = this.root.remove(this.offset + index); this.updateSizeAndModCount(-1); return result; }
- ltr
arrylist.iterator 触发内部类ltr
public Iterator<E> iterator() { return new ArrayList.Itr(); }
public ListIterator<E> listIterator(int index) { this.rangeCheckForAdd(index); return new ArrayList.ListItr(index); } public ListIterator<E> listIterator() { return new ArrayList.ListItr(0); }