顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。只要确定了起始位置,表中任一元素的地址都通过下列公式得到:LOC(ai)=LOC(a1)+(i-1)*L 1≤i≤n 其中,L是元素占用存储单元的长度。
简单点说就是:以数组的形式保存的线性表(属于线性表中的一种)
一下代码摘抄自JDK源码,我只摘抄了需要用到的部分。
add操作的第一步就是执行ensureCapacityInternal方法。
modCount++;这个一会儿会讲到
if (minCapacity - elementData.length > 0)
grow(minCapacity);//如果容量小了就执行grow(minCapacity)函数,看来grow(minCapacity)是扩容函数的庐山真面目啊
newCapacity = oldCapacity + oldCapacity / 2;
就是说每次当发现当前数组长度不足时,每次增加的步长是【0.5倍的当前长度】。
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
比方说你有个10容量的数组,现在要通过addAll()方法增加10个元素,那么minCapacity就是20,newCapacity就是15,15小于20那么newCacacity就变成了20.也就是说此次扩容了100%。
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
如果你的newCapacity比MAX_ARRAY_SIZE(Integer.MAX_VALUE - 8)还要大的话就要看看 hugeCapacity(int minCapacity) 方法了;
根据hugeCapacity(int minCapacity) 方法,newCapacity= Integer.MAX_VALUE
这次扩容的比例应该小于等于50%
网上有人说他每次扩容50%也是不准确的。
这其实Fail-Fast机制快速失败机制,这个机制以后再发博客吧。
transient 修饰的变量不会序列化,关于序列化的知识以后再详细说明吧。
Java中的数组都是静态数组(数组大小不可变)。
那ArrayList是基于动态数组实现的是不正确的吗?
ArrayList实现动态数组本质的创建新的数组,只是看起来原来的数组动态增长了!
这句话的正确与否取决于你对动态数组的理解和认识,你认为之前有个数组,之后创建一个新的可以算作“动态”那这句话是正确的。
如果你认为创建了一个新的,原来的是”静态“的,那么这句话是不正确的。
这个问题没有必要较真。
看看jdk里ArrayList的add方法是如何写的
问题就出在size++这边,主要分为两个步骤:
假设size=5.若线程A在5位置存放了值valueA,获得size=5,但还没来得及将size加1写入主存。此时线程B在也在5位置存放了值valueB,也获得size=5,而后A、B分别将size加1后写入主存,size=6,即两个线程执行两次add()后size只加了1。
1、ArrayList适合查找,不适合频繁的增删。
2、ArrayList不同步
3、如果可以确定ArrayList所需容量最好直接定义。