前一段时间开发任务比较轻松,所以学习了一些集合类的底层是如何封装的,今天就总结一下LinkList和ArrayList有哪些异同
相同点 |
我们可以发现,ArrayList和LinkedList都是接口List的实现类,也就是说他们两个类中一定都存在一些相同的方法,例如size()、isEmpty()、contains()、add()、remove()、get()、set()等,但是他们的实现却是大不相同
不同点 |
一、底层的数据结构
ArrayList是:基于动态数组结构
LinkedList:基于链表的数据结构
二、各性能的比较
数据结构的不同决定两者的性能各有优缺点。随机访问,ArrayList效率更高;而一般情况下任务,对于添加和删除操作,LinkedList表现更好,但是其实看源码就会发现,两者谁快谁慢并不是简简单单就能评判出来的,下边看一下两者get,remove,add三个方法的源码
ArrayList:
//set
public E set(int index, E e) {
rangeCheck(index);
checkForComodification();
E oldValue = ArrayList.this.elementData(offset + index);
ArrayList.this.elementData[offset + index] = e;
return oldValue;
}
//get
public E get(int index) {
rangeCheck(index);
checkForComodification();
return ArrayList.this.elementData(offset + index);
}
//add
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
//remove
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;
}
LinkedList:
//add
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
//set
public E set(int index, E element) {
checkElementIndex(index);
Node<E> x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}
//get
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
//remove
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
//节点定位
Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
我们会发现,当数组做删除或者添加的时候,都会使用到System.arraycopy()这个方法,这个方法描述的是数组中对象的移动过程,而linkedlist的添加或删除都用到了node()方法,这个方法是节点的定位,所以综合看来,这二者的速度就不太好确定了