1、LinkList的结构如下
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable { transient int size = 0; //第一个节点 transient Node<E> first; //最后一个节点 transient Node<E> last; //节点的结构 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; } } }
由上面可知,LinkList是一个双向列表结构
2、构造函数
//空的构造函数 public LinkedList() { } //传入集合的构造函数 public LinkedList(Collection<? extends E> c) { this(); addAll(c); }
和ArrayList对比可以发现,LinkedList没有容量的限制,不需要指定集合的大小。
3、元素添加
//1、添加单个元素。在最后一个元素后面添加 public boolean add(E e) { linkLast(e); return true; } //2、添加元素到指定位置 public void add(int index, E element) { checkPositionIndex(index); if (index == size) linkLast(element); else linkBefore(element, node(index)); } //3、添加到头元素 public void addFirst(E e) { linkFirst(e); } //4、添加到尾元素 public void addLast(E e) { linkLast(e); } //5、添加到集合 public boolean addAll(Collection<? extends E> c) { return addAll(size, c); }
主要调用了linkFirst和linkLast这两个方法
1) linkLast(E e)
void linkLast(E e) { final Node<E> l = last; //1、创建一个Node,prev指向last,netx为空 final Node<E> newNode = new Node<>(l, e, null); //2、last节点为新加的节点 last = newNode; //3、如果last节点为空,则说明新增加的节点newNode是第一个元素。 //否则,将原来的last节点的next复制为新的节点 if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }
4、删除操作
删除操作,总结起来就是unlink方法
E unlink(Node<E> x) { //获取当前节点的元素,前一个节点和后一个节点 final E element = x.item; final Node<E> next = x.next; final Node<E> prev = x.prev; //如果要删除节点的前一个节点为空,则说明要删除的元素就是第一个元素。 if (prev == null) { //将该元素的下一个节点赋值给first节点 first = next; } else { //如果要删除节点的前一个节点不为空。则将他前一个节点的next赋值为当前节点的next prev.next = next; x.prev = null; } //如果要删除的元素next为空,则说明要删除的元素是最后一个元素。 if (next == null) { //将该元素的前一个节点赋值给last last = prev; } else { next.prev = prev; x.next = null; } //将当前元素置为null x.item = null; size--; modCount++; return element; }
5、修改元素
public E set(int index, E element) { checkElementIndex(index); //获取到当前元素 Node<E> x = node(index); //老的元素 E oldVal = x.item; //将新的元素赋值给x.item x.item = element; return oldVal; }
6、查询元素
1) 按index查询元素。(查询第几个元素)
Node<E> node(int index) { //如果index在整个链表的前半部分,在从first往后查询 if (index < (size >> 1)) { Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } //如果index在整个链表的后半部分,在从last往前查询 else { Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } }
2) 按照对象查询元素的位置(index)
public int indexOf(Object o) { //从前往后遍历 int index = 0; if (o == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) return index; index++; } } else { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) return index; index++; } } return -1; }
ArrayList和LinkedList使用对比: Java ArrayList,LinkedList使用
原文:https://www.cnblogs.com/linlf03/p/12621283.html