- 知识脉络
- 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);
}