实现list接口的集合有序,可重复。set接口则相反无序,不可重复;
ArrayList:
一.底层
底层是动态数组结构,既拥有数组的特性;对于查询数据非常高效,添加数据需要改变数组后面元素移动位置,效率慢;
二:扩容源码解析
介绍的是无参构造方法:
public ArrayList() {
// elementData:底层数组 ,DEFAULTCAPACITY_EMPTY_ELEMENTDATA:空数组
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
通过List list = new ArrayList();根据构造方法可看出创建一个空数组;
对list添加数据: list.add(1);
/**
* 源码add的实现
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
1.ensureCapacityInternal(size + 1)方法进行扩容:
private void ensureCapacityInternal(int minCapacity) {
// minCapacity:数组最小大小
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
刚刚就是通过无参构造方法new的数组,所以数组elementData等于空数组;
2.判断数组默认值与数组最小size(minCapacity)比大小,返回最大值;因为是空数组所以minCapacity为1,数组默认值为10
即返回minCapacity=10;
3.是否扩容
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
modCount++暂且不说;原数组为空,所以elementData.length一定是0,即调用grow方法进行扩容;
4.扩容之后数组的新容量,并复制原数组
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
很清晰的看出扩容为原来的1.5倍(>>1:表示位运算,除以2),若扩容之后新容量还没有minCapacity大,
那么新容量大小等于minCapacity,复制原数组;
最后elementData[size++] = e;对数组添加元素;
LindedList:
一:底层
底层是链表结构,因为添加删除数据时只需要在相应的节点插入一个数据即可,所以对于添加删除非常高效;