JDK源码之LinkedList
2021/9/27 20:11:19
本文主要是介绍JDK源码之LinkedList,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
JDK源码之LinkedList
- 1. 全局变量
- 2. 构造器
- 3. 增删用到的双向链表的方法
- 4. 方法
- 5. 特性
- 6. ArrayList和LinkedList不同
1. 全局变量
// 列表容量 transient int size = 0; // 指向第一个节点的指针 transient Node<E> first; // 指向最后一个节点的指针 transient Node<E> last;
2. 构造器
// 构建一个空list public LinkedList() { } // 构建一个包含c的list public LinkedList(Collection<? extends E> c) { this(); addAll(c); }
tip:使用this关键字调用重载构造方法,避免相同的初始化代码,只能在构造方法中使用,必须位于构造方法的第一句。
3. 增删用到的双向链表的方法
双向链表是linkedList的基础。
// 将元素e作为linkedList最后一个元素; void linkLast(E e) {final Node<E> l = last; //取原本的最后一个节点 final Node<E> newNode = new Node<>(l, e, null); // new一节点 last = newNode; // 将新节点赋值给last if (l == null) // 前一个节点链接上新节点 first = newNode; else l.next = newNode; size++; //更新size和修改次数 modCount++;} // 将元素e作为linkedList第一个元素 private void linkFirst(E e) {final Node<E> f = first; //取原本的第一个节点 final Node<E> newNode = new Node<>(null, e, f); // new一个节点 first = newNode; //将新节点赋值给last if (f == null)//后一个节点链接上新节点 last = newNode; else f.prev = newNode; size++; //更新size和修改次数 modCount++;} // 去掉链表中首个元素f private E unlinkFirst(Node<E> f) { final E element = f.item; final Node<E> next = f.next; f.item = null; f.next = null; // help GC first = next; if (next == null) last = null; else next.prev = null; size--; modCount++; return element;} // succ节点前插入一个元素e void linkBefore(E e, Node<E> succ) { 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++;} // 去掉非null的最后一个元素 private E unlinkLast(Node<E> l) { 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;} // 去除某个非null元素 E unlink(Node<E> x) { final E element = x.item;// 1. 保存x节点的元素,前后元素的指针 final Node<E> next = x.next; final Node<E> prev = x.prev; if (prev == null) { // 2. x前一个元素链接x后一个元素 first = next;} else { prev.next = next; x.prev = null;} if (next == null) { //3. x后一个元素链接x前一个元素 last = prev;} else { next.prev = prev; x.next = null;} x.item = null;// 更新元素,容量和变更次数 size--; modCount++; return element;}
对于中间位置元素的增删,下面两个图可以很好的表示操作步骤:
插入操作示意图:(在c之前加入c1节点)
删除操作示意图:(删除c节点)
4. 方法
//在index位置插入c public boolean addAll(int index, Collection<? extends E> c) { 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); pred = succ.prev; } for (Object o : a) { //循环添加 @SuppressWarnings("unchecked") E e = (E) o; Node<E> newNode = new Node<>(pred, e, null); if (pred == null) //新链表 first = newNode; else pred.next = newNode; pred = newNode; } if (succ == null) { //添加完后链接起来 last = pred; } else { pred.next = succ; succ.prev = pred; } size += numNew; modCount++; return true; }
5. 特性
LinkedList继承了Deque接口,具有队列的特性,同时作为双端队列,LinkedList还具有栈的特性。
队列方法:
栈:
public void push(E e) { addFirst(e); } public E pop() { return removeFirst(); }
6. ArrayList和LinkedList不同
- LinkedList不支持随机访问,因此访问非首尾元素效率较低,时间复杂度为O(n),访问首尾时间复杂度为O(1)。
- 相比于ArrayList, LinkedList的优势在于插入、删除操作,只需要改变前后两个元素的指针,不需要移动后面的元素。
- LinkedList由双向链表实现,具有队列和栈的特性。ArrayList由数组实现。
这篇关于JDK源码之LinkedList的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南