Java容器源码LinkedList原理解析
作者:yaominghui 发布时间:2023-06-03 02:06:23
标签:Java,容器,LinkedList
LinkedList简介
LinkedList是一个使用双向链表结构实现的容器,与ArrayList一样,它能动态扩充其长度,LinkedList相较于ArrayList,其任意位置插入速度比ArrayList要快,但是其查询速度要比ArrayList要慢;LinkedList继承自AbstractSequentialList,实现了List、Deque、Cloneable、Serializable接口。
LinkedList UML图如下:
和ArrayList一样,LinkedList也不是一个线程安全的容器。
LinkedList源码分析
构造方法
LinkedList有两个构造方法:
public LinkedList() {
}
//从已有的一个容器创建一个LinkedList对象
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
addAll()方法:
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;
//获取第index位置的node元素和node的前一个元素
//succ:第index位置的node元素
//pred:index位置前一个node元素
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;
}
add方法
LinkedList也有两个add方法,如下:
public boolean add(E e) {
//添加元素到队尾
linkLast(e);
return true;
}
public void add(int index, E element) {
//检查index是否溢出
checkPositionIndex(index);
if (index == size)
//index == size,直接添加到队尾
linkLast(element);
else
//index != size,添加元素到index位置
linkBefore(element, node(index));
}
linkLast方法:
void linkLast(E e) {
final Node<E> l = last;
//新建一个node,将其前一个元素指针指向原链表的最后一个元素
final Node<E> newNode = new Node<>(l, e, null);
//更新尾指针
last = newNode;
if (l == null)
//若原last==null说明此时链表就一个元素
first = newNode;
else
//更新原链表尾元素指针
l.next = newNode;
size++;
modCount++;
}
linkBefore方法:
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
//获取指定位node元素的前一个元素pred
final Node<E> pred = succ.prev;
//新建一个node,将其前指针指向pred元素
final Node<E> newNode = new Node<>(pred, e, succ);
//将指定位置的node元素的前指针指向新元素,完成插入
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
获取指定位置node指针方法node:
Node<E> node(int index) {
// assert isElementIndex(index);
//index > size/2时,说明在链表前半段,从前往后搜索
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
//index < size/2时,从后往前搜索
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
get方法也比较简单,首先检测index是否溢出,然后直接找到index位置的元素,并返回其item。
来源:https://www.cnblogs.com/Sirius-/p/13934542.html


猜你喜欢
- 此文通过一段代码来展示java获取相关参数的方法分享给大家:public static void main(String[] args) {
- 监控给定的域名,一旦域名连续30秒(这是默认值,可以在源码中修改)无法Ping通,立刻发邮件到指定邮箱,并发短信给站长 原理: 用后台线程循
- 前言以下内容科班同学学过UML和数据库的应该比较熟悉数据模型:数据模型是对数据库特征的抽象,也就是用户从数据库中看到的模型,例如一张数据表或
- 本文实例讲述了C#使用foreach语句简单遍历数组的方法。分享给大家供大家参考。具体如下:using System;public clas
- 在网站开发中经常遇到级联数据的展示,比如选择城市的时候弹出的省市县选择界面。很多前端制作人员习惯于从JSON中而不是从数据库中获
- 初始化方式一:@PostConstruct注解假设类UserController有个成员变量UserService被@Autowired修饰
- 本文实例讲述了Java Scanner类用法及nextLine()产生的换行符问题。分享给大家供大家参考,具体如下:分析理解:Scanner
- 前言对于Android注解,或多或少都有一点接触,但相信大多数人都是在使用其它依赖库的时候接触的。因为有些库如果你想使用它就必须使用它所提供
- 五丶封装(1)包的概念与创建1>概念在我们的电脑上有许多的文件,我们为了方便管理,大致给它们进行了不同的命名。然后在不同的文件夹下面再
- 对于触摸屏,其原生的消息无非按下、抬起、移动这几种,我们只需要简单重载onTouch或者设置触摸 * setOnTouchListener即
- 关于这个的例子其实网上已经有这方面的资料了,但是为了文章的完整性,还是觉得有必要讲解.我们先来看一下效果:  
- JVM内存模型/内存空间Java虚拟机JVM运行起来,就会给内存划分空间,这块空间成为运行时数据区。运行时数据区主要划分为以下 6
- 网上很多资料在描述Java内存模型的时候,都会介绍有一个主存,然后每个工作线程有自己的工作内存。数据在主存中会有一份,在工作内存中也有一份。
- 这篇文章主要介绍了JavaWeb如何实现禁用浏览器缓存,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋
- spring boot 作为微服务的便捷框架,在错误页面处理上也有一些新的处理,不同于之前的spring mvc 500的页面处理是比较简单
- 一 前言在elasticsearch\config目录下,有三个核心的配置文件:elasticsearch.yml,es相关的配置。jvm.
- 本文实例为大家分享了Android Camera1实现预览框显示的具体代码,供大家参考,具体内容如下Android要预览Camer界面其实非
- 本文实例讲述了C#异步执行任务的方法。分享给大家供大家参考。具体如下:// 异步执行耗时任务(适合不需要等它的执行结果的场景,如发邮件、发短
- springMVC是spring的一个模块,专门做web的。SpringMVC请求处理过程:请求发送,根据url-pattern,转发发送给
- 0x001 算数运算符 int num1 = 1, num2 = 2; System.o