arrayList和linkedList都是list接口的实现类,arrayList是基于动态数组实现的,LinkedList是基于双向链表是实现的。
数组是内存中一段连续的存储空间。
未命名文件 (1).png
链表是一种物理存储单元上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构操作复杂(百度百科)。
未命名文件 (2).png
ArrayList和LinkedList的区别主要由三点:
1.arrayList基于动态数组,linkedList基于双向链表。
2.对于get和set操作arrayList优于linkedList
3.对于add和remove操作linkedList优于arrayList
第一个区别显而易见,不再多说。
对于第二个区别:对于get和set操作arrayList优于linkedList
arrayList的get方法
public E get(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
return (E) elementData[index];
}
linkedList的get方法
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
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;
}
}
从实现逻辑上可以看出,arrayList可以直接通过角标获取某个元素,而linkedList需要从第一个开始一个一个找所以更耗时(set方法同理)。
第三个区别:对于add和remove操作linkedList优于arrayList
arrayList的add方法
public void add(int index, E element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
linkedList的add方法
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
arrayList的add方法每次插入都需要copy原数组扩容,copy数组的操作是比较耗时的。
linkedList每次插入需要创建新的节点并指明前驱和后继,保证指针指向正确。copy数组的操作相对这个操作是比较耗时的。
网友评论