有关LinkedList常用方法的源码解析
jdk1.7.0_79
上文里解析了有关ArrayList中的几个常用方法的源码——《有关ArrayList常用方法的源码解析》,本文将对LinkedList的常用方法做简要解析。
LinkedList是基于链表实现的,也就是说它具备了链表的优点和缺点,随机访问慢、插入删除速度快。既然是链表,那么它就存在节点数据结构,也不存在容量大小的问题,来一个在尾部添加一个。
//LinkedList$Node 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; } }
第一个默认不带参数的构造方法,构造一个空链表。
//1.LinkedList,默认构造方法 public LinkedList() { }
第二个构造方法能把一个集合作为一个参数传递,同时集合中的元素需要是LinkedList的子类。
//2.LinkedList,能将一个集合作为参数的构造方法 public LinkedList(Collection<? extends E> c) { this(); addAll(c); }
两个构造方法都比较简单,接下来看元素的插入及删除等方法。
public boolean add(E e) { linkLast(e); //将元素添加到链表尾部 return true; }
//LinkedList#linkLast 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++; //链表数据总数+1 modCount++; //modCount变量在《有关ArrayList常用方法的源码解析》提到过,增删都会+1,防止一个线程在用迭代器遍历的时候,另一个线程在对其进行修改。 }
学过《数据结构》的同学相信看到链表的操作不会感到陌生,接着来看看删除指定位置的元素remove(int)方法。
//LinkedList#remove public E remove(int index) { checkElementIndex(index); //检查是否越界 index >= 0 && index <= size return unlink(node(index)); //调用node方法查找并返回指定索引位置的Node节点 }
//LinkedList#node,根据索引位置返回Node节点 Node<E> node(int index) { if (index < (size >> 1)) { //size >> 1 = size / 2,如果索引位于链表前半部分,则移动fisrt头指针进行查找 Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { //如果索引位于链表后半部分,则移动last尾指针进行查找 Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } }
查找到index位置的Node后,调用unlink方法摘掉该节点。
//LinkedList#unlink,一看即懂 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) { first = next; } else { prev.next = next; x.prev = null; } if (next == null) { last = prev; } else { next.prev = prev; x.next = null; } x.item = null; size--; modCount++; return element; }
从代码中就能看出LinkedList和ArrayList两者的优缺点,由于只涉及简单的链表数据结构,所以不再对其他方法进行解析。
不积跬步,无以至千里;不积小流,无以成江海。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?