链表源码很简单
看核心数据结构
private transient Entry<E> header = new Entry<E>(null, null, null);
一个头节点。
再看下Entry<E>的结构
E element;
Entry<E> next;
Entry<E> previous;
这就是双项链表Entry<E>的结构
看看里面方法实现
private Entry<E> entry(int index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); Entry<E> e = header; if (index < (size >> 1)) { for (int i = 0; i <= index; i++) e = e.next; } else { for (int i = size; i > index; i--) e = e.previous; } return e; }
private Entry<E> entry(int index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); Entry<E> e = header; if (index < (size >> 1)) { for (int i = 0; i <= index; i++) e = e.next; } else { for (int i = size; i > index; i--) e = e.previous; } return e; }
基于 index的添加与删除都是先和 中间位置比较
基于 Object的比较和删除 则都是从头节点开始查找 同样有 modCount属性。
2. ArrayList
核心数据结构
private transient Object[] elementData;
默认容量是10
在表末尾的增删操作 速度很快 o(1)级别
下面看一下随机位置添加 删除的代码
public void add(int index, E element) { if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); ensureCapacity(size+1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; }
删除后会有一个调整数组的操作。迭代器同样拥有快速失效的特性
两者性能比较, LinkedList 适用于随机增删,但是前提是表不大, 不然搜索操作会很费时, ArrayList 读元素和末尾写速度很快,其主要操作都有数组调整的过程,
但是数组是内存中连续一块的时间,移动速度较快