详解Java 集合系列(三)—— LinkedList
作者:那一叶随风 发布时间:2022-01-30 16:49:10
标签:Java,LinkedList
LinkedList
LinkedList是一种可以在任何位置进行高效地插入和删除操作的有序序列。
它的最基本存储结构是一个节点:每个节点将存储对象,以及前后节点的引用。
结构图
从上面的结构图中,我们可以了解到 ListedList 底层是基于双向链表实现的。
围起来的可以看成 LinkedList 类,它定义了三个 transient 成员变量:first、last、size。这三个变量是整个 LinkedList 类的关键点。
由于是双向链表(每个node都有保存前后节点的引用),因此我们不管是由 first 还是 last 节点开始迭代,都可以将整个链表的数据找出来;
在查询、随机插入以及set等操作都有涉及 size 判断;
由于 LinkedList 是双向链表,类中只存储了首尾两个节点,因此查询第n个元素都要从头遍历进行查找。
源码分析
add(E e) 源码分析
/**
* Appends the specified element to the end of this list.
*
* <p>This method is equivalent to {@link #addLast}.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
linkLast(e);
return true;
}
/**
* Links e as last element.
*/
void linkLast(E e) {
final Node<E> l = last; // 将当前最后一个元素寄存在 l
final Node<E> newNode = new Node<>(l, e, null); // new 一个新节点:pre的引用为l;存储元素为e;next的引用为null
last = newNode; // 将新节点引用覆盖成员变量 last
if (l == null)
first = newNode; // 若l为null,说明之前链表为空,此时新节点为首个元素
else
l.next = newNode; // 否则,更新l的next引用
size++; // size+1
modCount++; // 非查询操作 modCount 都会 +1
}
add(int index, E element) 方法分析
/**
* Inserts the specified element at the specified position in this list.
* Shifts the element currently at that position (if any) and any
* subsequent elements to the right (adds one to their indices).
*
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
checkPositionIndex(index); // 检查 index 是否大于 size
if (index == size)
linkLast(element); // 直接在链表末尾追加
else
linkBefore(element, node(index)); // 插入index 节点前面
}
// 检查 index 是否超出范围 超出则抛出 IndexOutOfBoundsException
private void checkPositionIndex(int index) {
if (!isPositionIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/**
* Tells if the argument is the index of a valid position for an
* iterator or an add operation.
*/
private boolean isPositionIndex(int index) {
return index >= 0 && index <= size;
}
/**
* 根据 index 查找 node
* 该方法利用了双向链表的特性,index 距离哪个链表头近就从哪边开始开始遍历
* 时间复杂度为 O(n/2);
* 当 index 接近 size 的中间值时,效率最低
* Returns the (non-null) Node at the specified element index.
*/
Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) { // size 右移一位(除以2)
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
优缺点
优点
增删元素效率高(只需要更新节点附近的引用即可)
缺点
由于查询需要进行遍历,因此效率低
知识脑图
以上所述是小编给大家介绍的Java 集合系列(三)—— LinkedList详解整合网站的支持!
来源:https://www.cnblogs.com/phpstudy2015-6/p/10626564.html#_label1


猜你喜欢
- Flyweight定义:避免大量拥有相同内容的小类的开销(如耗费内存),使大家共享一个类(元类)。为什么使用共享模式/享元模式面向对象语言的
- 在初始化自己位置的时候请求定位权限:Constants.ACCESS_FINE_LOCATION_COMMANDS_REQUEST_CODE
- 最近在做项目的时候发现,微服务使用feign相互之间调用时,存在session丢失的问题。例如,使用Feign调用某个远程API,这个远程A
- 用Dockerfile 构建一个java的编译环境,这里整理下实现步骤:1、包括以下软件包ubuntujdkmavensvn2、jdk、ma
- 解锁、唤醒屏幕用到KeyguardManager,KeyguardLock,PowerManager,PowerManager.WakeLo
- 详解微信小程序 同步异步解决办法小程序中函数体还没有完成,下一个函数就开始执行了,而且两个函数之间需要传参。那是因为微信小程序函数是异步执行
- idea删除模块后重新创建显示该模块已经被注册原因:注册信息没有删除干净解决方案:找到gradle.xml,modules.xml,work
- Pom文件的依赖我们进入POM文件,首先是看到的是Pom文件中的parentparent是Spring Boot的框架版本控制中心<!
- Android仿微信activity滑动关闭功能1.利用具体利用v4包下的slidingPaneLayout实现透明的activity,代码
- 本文实例为大家分享了WPF实现轮播图切换效果的具体代码,供大家参考,具体内容如下实现效果如下:步骤:1、自定义控件MyImageContro
- 一、新建项目我们这次直接从IEDA创建项目,具体配置如下,还是万年的Java8。二、docker-compose 配置mongoDBdock
- RTF文档即富文本格式(Rich Text Format)的文档。我们在处理文件时,遇到需要对文档格式进行转换时,可以将RTF转为其他格式,
- 通过邮件找回密码功能的实现1、最近开发一个系统,有个需求就是,忘记密码后通过邮箱找回。现在的系统在注册的时候都会强制输入邮箱,其一目的就是
- 这篇文章首先介绍了在SpringBoot中如何获得项目的编译时间和版本号,并向外提供接口,然后介绍了介绍了新版maven获得时间戳时区错误的
- 队列在编程语言中是如何定义的呢?小编与大家分享自己的经验。队列的定义队列是限制结点插入操作固定在一端进行,而结点的删除操作固定在另一端进行的
- 本文实例为大家分享了Java通讯录系统的具体代码,供大家参考,具体内容如下import java.util.Scanner;class Pe
- 本文介绍的是关于Mybatis中用OGNL表达式处理动态sql的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍:常用的Mybat
- 最近在做一个项目,遇到了项目打成 war 包的一个问题,项目创建时选择的时 jar 包方式,后因项目部署要求,需要打成 war 包部署,遇到
- 开发前准备支付宝开发平台.支付宝沙箱环境申请使用!!!重点 授权回调地址必须要写全路径也就是controller最终路径(下面有具体细节)R
- 一、定义实体类Person,封装生成的数据package net.dc.test;public class Person { private