LinkedList 是链表实现的线性表(双链表),元素有序且可以重复。
LinkedList继承AbstractSequentialList并且实现了List和Deque,Cloneable, Serializable接口。
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.SerializableNode 类,这是 LinkedList 类中的一个内部类,集合里每一个元素就代表一个 Node 类对象,LinkedList 集合就是由许多个 Node 对象类似于手拉着手构成,由此可知,LinkedList是一个双向链表。
private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { //存放数据 this.item = element; //该节点上一节点的引用 this.next = next; //该节点下一节点的引用 this.prev = prev; } }每个节点都prev都保存上一个节点的引用,next保存下一个节点的引用;
这里只介绍add(E e),addFirst(E e),addLast(E e)和 实现类似。
将元素插入指定位置 public void add(int index, E element) { //判断索引是否越界 checkPositionIndex(index); if (index == size) //如果索引值等于链表大小,则直接在链尾添加元素 linkLast(element); else linkBefore(element, node(index)); } //根据索引获取节点,因为是链表,不像数组,在内存中并不是一块连续的位置存储,不能根据索引直接取到值,需要从头部或者尾部一个个向下找 Node<E> node(int index) { //size >> 1表示移位,指除以2的1次方 if (index < (size >> 1)) {//如果索引比链表的一半小 Node<E> x = first;//设x为头节点,表示从头节点开始遍历 for (int i = 0; i < index; i++)//因为只需要找到index处,所以遍历到index处就可以停止 x = x.next;//从第一个节点开始向后移动,直到移动到index前一个节点就能找到index处的节点 return x; } else {//如果索引比链表的一半大 Node<E> x = last;//设x为尾部节点,表示从最后一格节点开始遍历 for (int i = size - 1; i > index; i--) x = x.prev;//从最后一个节点开始向前移动,直到移动到index后一个节点就能找到index处的节点 return x; } } void linkBefore(E e, Node<E> succ) { //获取index 节点的上一个节点 final Node<E> pred = succ.prev; //新增一个节点,prev指向pred,e为新加元素,next指向succ节点 final Node<E> newNode = new Node<>(pred, e, succ); //succ的prev指向新节点 succ.prev = newNode; //如果插入节点的上一个节点引用为空 if (pred == null) //头部节点设为新节点 first = newNode; else //原始index的上一个节点的next 设为新节点 pred.next = newNode; //链表长度+1 size++; modCount++; }返回链表中第一个出现指定元素的索引
public int indexOf(Object o) { int index = 0; if (o == null) {//查找的元素为null for (Node<E> x = first; x != null; x = x.next) {//从头结点开始不断向下一个节点进行遍历 if (x.item == null) return index;//找到了则返回index index++; } } else {//查找的元素不为null for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item))//使用equals 比较 return index;//找到了则返回index index++; } } return -1;//找不到指定元素,则返回-1 }