LinkedList-链表集合
来源:互联网 发布:欧陆风云4秘籍源码军事 编辑:程序博客网 时间:2024/06/15 04:34
LinkedList 底层是由链表实现的,每个链表节点含有上一个节点及下一个节点的引用,同时内部封装了元素的引用。 下面是linkedList在部分代码的jdk源码分析,仔细看linkedList实现,不难发现为何linkedList查询慢,增删快。
package java.util;import java.util.function.Consumer;//省略类似代码分析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; public LinkedList() { } public LinkedList(Collection<? extends E> c) { this(); addAll(c); } //将元素添加到第一个节点 private void linkFirst(E e) { final Node<E> f = first; //原首节点 //nowNode.next = f 下一个节点 //nowNode.item = e 元素 final Node<E> newNode = new Node<>(null, e, f); first = newNode; //新首节点指向 if (f == null) last = newNode; //原首节点为null则只有该一个新节点 else f.prev = newNode; //修改原首节点的 前指向 size++; modCount++; } /** * Links e as last element. */ void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; } //将元素e插入到 succ节点前 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) //succ为节点头 first = newNode; else pred.next = newNode; //将pred置为succ的前一个节点 size++; modCount++; } //将首节点f移出链表 private E unlinkFirst(Node<E> f) { // assert f == first && f != null; final E element = f.item; // 获取f节点元素reference final Node<E> next = f.next; //获取f节点下一个节点reference f.item = null; //将f节点元素置为null f.next = null; //将f节点的下一个指向为null first = next; //将f节点的下一个元素置为链表首节点reference if (next == null) //如果f节点的下一个节点为null 则该链表只有f一个节点 last = null; //移除后链表都指向null else next.prev = null; //否则将新首节点(f节点的下一个节点)的前一个节点置为null(链表头) size--; modCount++; return element; } /** * Unlinks non-null last node l. */ private E unlinkLast(Node<E> l) { // assert l == last && l != null; final E element = l.item; final Node<E> prev = l.prev; l.item = null; l.prev = null; // help GC last = prev; if (prev == null) first = null; else prev.next = null; size--; modCount++; return element; } //将节点移出链表 E unlink(Node<E> x) { // assert x != null; final E element = x.item; //节点元素 final Node<E> next = x.next; //该节点下一个指向 final Node<E> prev = x.prev; //该节点上一个指向 if (prev == null) { //如果该上一个节点为null 则原节点为链表头 first = next; //将该下一个节点置为新首节点 } else { //该节点原上一个节点的下一个节点指向该节点的原下一个节点 (将该节点从上一个节点的引用中移除) prev.next = next; x.prev = null; //置为null } //同理 (将该节点从下一个节点的引用中移除) if (next == null) { last = prev; } else { next.prev = prev; x.next = null; } x.item = null; //置为null size--; modCount++; return element; } //获取首节点 public E getFirst() { final Node<E> f = first; if (f == null) throw new NoSuchElementException(); return f.item; //直接返回首节点的元素 } /** * Returns the last element in this list. * * @return the last element in this list * @throws NoSuchElementException if this list is empty */ public E getLast() { final Node<E> l = last; if (l == null) throw new NoSuchElementException(); return l.item; } //移除第一个节点元素 public E removeFirst() { final Node<E> f = first; if (f == null) throw new NoSuchElementException(); return unlinkFirst(f); //将首节点移出链表 } /** * Removes and returns the last element from this list. * * @return the last element from this list * @throws NoSuchElementException if this list is empty */ public E removeLast() { final Node<E> l = last; if (l == null) throw new NoSuchElementException(); return unlinkLast(l); } //插入元素到链表头 public void addFirst(E e) { linkFirst(e); } public void addLast(E e) { linkLast(e); } //检验是否包含该元素 public boolean contains(Object o) { return indexOf(o) != -1; } //返回节点个数 public int size() { return size; } //插入元素 public boolean add(E e) { linkLast(e); //插入元素是默认插入链尾 return true; } //删除指定元素 成功返回true 否则返回false public boolean remove(Object o) { if (o == null) { //遍历链表如果含有该元素则移出链表 for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); //将元素移除链表 return true; } } } else { //同理 for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { unlink(x); return true; } } } return false; } //将集合中的元素全部添加到链表中 public boolean addAll(Collection<? extends E> c) { return addAll(size, c); } //将指定位置将集合所有元素添加在链表中 public boolean addAll(int index, Collection<? extends E> c) { //判断index是否下标越界 checkPositionIndex(index); Object[] a = c.toArray(); int numNew = a.length; if (numNew == 0) return false; Node<E> pred, succ; //定义 if (index == size) { //在链表尾添加 succ = null; pred = last; } else { succ = node(index); //获取index下标的指定节点 pred = succ.prev; } //在pred后逐步添加节点, for (Object o : a) { //迭代将newNode添加 上述pred节点的下一个节点 @SuppressWarnings("unchecked") E e = (E) o; Node<E> newNode = new Node<>(pred, e, null); //创建节点 pred 为该节点的上一个指向,e为节点元素 if (pred == null) //如果pred为null 则原链表长度为0 first = newNode; else pred.next = newNode; //将pred节点下一个指向标记为newNode pred = newNode; //重复利用pred引用指向 } if (succ == null) { last = pred; } else { pred.next = succ; //此时的pred节点 为 Object[]数组的最后一个元素 a[a.length-1] succ.prev = pred; //将pred节点与 原链表中index下标节点连接 } size += numNew; modCount++; return true; } //清除所有节点 public void clear() { //循环清除所有节点的引用 for (Node<E> x = first; x != null; ) { Node<E> next = x.next; x.item = null; x.next = null; x.prev = null; x = next; } first = last = null; //首尾置为null size = 0; modCount++; } //从指定位置获取元素 public E get(int index) { checkElementIndex(index); //防止下标越界 return node(index).item; //获取index下标的指定节点 } //将指定位置的元素替换为新元素 public E set(int index, E element) { checkElementIndex(index); Node<E> x = node(index); //获取index下标的指定节点 E oldVal = x.item; x.item = element; //替换该节点的元素 return oldVal; //返回原元素 } //在指定位置添加新元素 public void add(int index, E element) { checkPositionIndex(index); //防止下标越界 if (index == size) linkLast(element); //将元素添加到最后节点 else linkBefore(element, node(index)); //在index下标节点前插入元素 } //从指定位置删除元素 public E remove(int index) { checkElementIndex(index); return unlink(node(index)); //将指定节点移出链表 } //获取index下标的节点 Node<E> node(int index) { // assert isElementIndex(index); //判断index的位置 折半比较 if (index < (size >> 1)) { Node<E> x = first; //小于一般 从first开始遍历 for (int i = 0; i < index; i++) x = x.next; //迭代指向 (遍历) return x; //确定该index位置下的节点 } else { //同理 Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } } //返回该元素在链表的节点位置 不包含该节点则返回-1 public int indexOf(Object o) { int index = 0; if (o == null) { //linkedList 是可以存储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; //不含有该元素 }
0 0
- LinkedList-链表集合
- LinkedList链表集合
- 集合 --- LinkedList
- LinkedList集合
- 集合-LinkedList
- 《数据结构和Java集合框架第三版》读书笔记(六)LinkedList双向链表
- Java集合类--LinkedList
- 【集合】LinkedList链表类
- 19、集合之LinkedList
- JAVA 集合框架 LinkedList
- Java集合类--LinkedList
- 集合之LinkedList
- LinkedList集合整理
- 集合框架 LinkedList
- 19、集合之LinkedList
- java集合(LinkedList)
- Java集合之LinkedList
- java集合之LinkedList
- mybatis输出高级映射(一对多查询)
- Swift3 创建字典
- 慢慢python之路----心情笔记
- 【Codeforces 283 C. Coin Troubles】+ 拓扑序 + 完全背包
- Linux常用命令
- LinkedList-链表集合
- 第6
- 使用OpenCV来进行人脸识别
- (贪心,区间选点问题) Radar Installation POJ 1328
- 算法导论 练习题 11.2-1
- SSH框架搭建 详细图文教程
- xdoj 1188: 大大数星星
- POJ3107Godfather找重心
- 卡尔曼滤波简介+ 算法实现代码