相同点:
1. 都是List的子类。 2. 允许空值
区别:
ArrayList: 1. 内部是数组结构实现 2. 数据的插入和删除都需要对数组复制和重排序(删除和插入比较慢) 3. 有序可以重复 4. 插入和删除比较慢 5. 查找效率高 linkList: 1. 双向链表结构,对每一个元素都有指向前后元素的指针 2. 顺序读取效率比较高,随机读取元素效率比较低 3. 删除、插入效率高 4. 查询比较慢二、ArrayList 添加元素
在查看源代码过程当中可以发现:当我们使用add(index,element) ; 方法时,在某个位置添加一个元素的操作,举例:add(0,5),在第一个位置加入一个5的元素。
public void add(int index, E element) {
// 比对下标和数据长度或者下标小于0,否则抛出数据下标越界
rangeCheckForAdd(index);
//DEFAULT_CAPACITY = 10 默认的容量是 10 ,最小值和默认参数对比(取最大的那个作为最小容量)
ensureCapacityInternal(size + 1); // Increments modCount!!
//移位复制 arraycopy,将 index 的位置空出去,本地方法C/c++写的。
System.arraycopy(elementData, index, elementData, index + 1,size - index);
//添加index元素
elementData[index] = element;
//数组长度自增
size++;
}
//10容量
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
//对比是否需要扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
//计算容量
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);
}
直接add的方式:
public boolean add(E e) {
//自增容量,跟前面的指定位置存放是一样的
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
三、ArrayList 删除元素
删除的方法都是:remove(Object / index)
第一种:list 删除指定位置(index)的数据
public E remove(int index) {
//检查是否下标越界
rangeCheck(index);
modCount++;
//获取需要删除的元素
E oldValue = elementData(index);
int numMoved = size - index - 1;
//元素移动,左移
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
第二种:list 删除数据对象,不管在哪个位置
//返回是否删除
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
//并非null的时候,是在全数组的方式遍历获取在删除的。
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
四、linkList 添加元素
public boolean add(E e) {
//默认方式
linkLast(e);
return true;
}
//添加元素
void linkLast(E e) {
final Node l = last;
final Node newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
//第一次添加元素
first = newNode;
else
//节点的下一个值
l.next = newNode;
size++;
modCount++;
}
五、linkList 删除元素
第一种方式:index
public E remove(int index) {
checkElementIndex(index);
//
return unlink(node(index));
}
Node node(int index) {
// assert isElementIndex(index);
// size >> 1 如果size = 32,size >> 1 = 16 ,分成两部分查找
if (index < (size >> 1)) {
Node x = first;
//遍历节点
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
E unlink(Node x) {
// assert x != null;
final E element = x.item;
final Node next = x.next;
final Node prev = x.prev;
if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
}
if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}
第二种方式:object
public boolean remove(Object o) {
if (o == null) {
for (Node x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}
四、总结
通过上述的源代码方式:我们可以看出ArrayList的添加和删除是通过移位复制,并且是系统本地方法(具体想深入研究的和话可以下载arrayCopy C++ 代码实现),删除会遍历所有的元素,不确定性很大。所以在删除和添加操作是比较慢的



