Java中LinkedList实现原理
数据结构
LinkedList是基于链表结构实现,所以在LinkedList类中包含了first和last两个指针(类型为Node)。Node中包含了对prev节点、next节点的引用,这样就构成了双向的链表。
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.add(E e)方法
该方法首先声明一个新Node l,将链表的最后一个Node赋值给l,然后将新的Node即newNode覆盖last(或者说让last指向newNode),最后将l的next指针指向newNode。
//Appends the specified element to the end of this list.
public boolean add(E e) {
linkLast(e);
return true;
}
/**
* 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++;
}
2.add(int index, E element)
该方法是在指定的index位置插入新元素。如果index位置正好等于size,则调用linkLast(element)将其插入到末尾;否则调用linkBefore(element, node(index))方法进行插入。
linkBefore中的node(index)是返回指定位置的元素。
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
/**
* Returns the (non-null) Node at the specified element index.
*/
Node<E> node(int index) {
// assert isElementIndex(index);
// 如果要取元素的位置是整个list一半的左半边,那么从list的头开始向后遍历,遍历至要取元素的位置
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
}
// 否则从list一半的右半边开始寻找,也就是从尾部开始向前遍历,遍历至要取元素的位置
else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
删除
1.remove(int index)
删除列表中指定位置的元素,首先检测该位置是否在该列表中存在,然后解除该元素前、后指向的元素。
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
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;
}
获取
1.get(int index)
获取指定位置元素的值。同样首先判断传入位置是否越界,如果超过list的size,抛出IndexOutBoundsException异常,然后node()方法进行左半边或右半边遍历获取,add(int index, E element)中有提到,不再赘述。
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
2.getFirst()
3.getLast()
first、last是LinkedList的两个属性,判空后直接返回。
/**
* Returns the first element in this list.
*
* @return the first element in this list
* @throws NoSuchElementException if this list is empty
*/
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;
}
Java中LinkedList实现原理的更多相关文章
- 转载-Java中LinkedList的一些方法—addFirst addFirst getFirst geLast removeFirst removeLast
Java中LinkedList的一些方法—addFirst addFirst getFirst geLast removeFirst removeLast 版权声明:本文为博主原创文章,遵循CC 4. ...
- 6.Java集合-LinkedList实现原理及源码分析
Java中LinkedList的部分源码(本文针对1.7的源码) LinkedList的基本结构 jdk1.7之后,node节点取代了 entry ,带来的变化是,将1.6中的环形结构优化为了直线型链 ...
- java 中LinkedList的学习
Java中,所有链表实际上都是双向链表的,即每个结点还存放在着指向前驱结点的引用. LinkedList中的contains方法检测某个元素是否出现在链表中. LinkedList类提供了一个用来访问 ...
- Java中LinkedList的remove方法真的耗时O(1)吗?
这个问题其实来源于Leetcode的一道题目,也就是上一篇日志 LRU Cache.在使用LinkedList超时后,换成ArrayList居然AC了,而问题居然是在于List.remove(Obje ...
- 深入介绍Java中的锁[原理、锁优化、CAS、AQS]
1.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 2.锁实现的基本原理 2.1.volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新, ...
- Java中的CAS原理
前言:在对AQS框架进行分析的过程中发现了很多CAS操作,因此有必要对CAS进行一个梳理,也便更清楚的了解其原理. 1.CAS是什么 CAS,是compare and swap的缩写,中文含义:比较交 ...
- java中JVM的原理
转载:https://blog.csdn.net/witsmakemen/article/details/28600127 一.java虚拟机的生命周期: Java虚拟机的生命周期 一个运行中的Jav ...
- Java中LinkedList的fori和foreach效率比较
在<Java中ArrayList的fori和foreach效率比较>中对ArrayList的两种循环方式进行了比较,本次对LinkedList的两种遍历方式进行效率的比较. 1. list ...
- java中JVM的原理重温【转】
一.基础理论知识 1.java虚拟机的生命周期: Java虚拟机的生命周期 一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序.程序开始执行时他才运行,程序结束时他就停止.你在同一台机器上 ...
随机推荐
- WAMP 默认mysql密码修改
WAMP安装好后,mysql密码是为空的,那么要如何修改呢?其实很简单,通过几条指令就行了,下面我就一步步来操作. 首先,通过WAMP打开mysql控制台. 提示输入密码,因为现在是空,所以直接按回车 ...
- win8 应用商店程序使用SQLITE数据库
http://www.cnblogs.com/zhuzhenyu/archive/2012/11/27/2790193.html using SQLite; using System; using S ...
- 修复 dji spark 的 micro sd/tf 存储卡里不能正常播放的视频文件
可能是因为 1.在没有正确的操作停止录像前,关掉了 spark 的电源 2.在 spark 没有完成视频存储前,关掉了 spark 的电源 总之在电脑里想查看存储卡里的视频时,发现居然无法播放,这就太 ...
- [MeetCoder] Crossing Bridge
Crossing Bridge Description N people wish to cross a bridge at night. It’s so dark around there that ...
- 史上最全PHP正则表达式实例汇总
收集了一份php正则表达式的实例教程,真心不错,记录下. 正则表达式用于字符串处理.表单验证等场合,实用高效. 一些常用的表达式: $str = preg_replace("/(<a. ...
- cocos2d-x---CCLabelTTF加载字体库
strPath = g_ImgPath + "方正卡通简体.ttf"; m_pLebGold = CCLabelTTF::create(); CC_ERROR(m_pLebGold ...
- [SQL Server 2014] 微软将于年底发布新版数据库SQL Server 2014
在今年的TechEd大会上,微软宣布SQL Server 2014的第一个技术预览版.SQL Server 2014的重点包括内存OLTP.实时的大数据分析.支持混合云端,以及提供更完整的商业智能(B ...
- 每日英语:Six Ways to Modernize Your Car
AS AUTO MAKERS ADD far-out features to the latest cars at warp speed--everything from futuristic hea ...
- 每日英语:Why Mom's Time Is Different From Dad's Time
Several years ago, while observing a parenting group in Minnesota, I was struck by a confession one ...
- (转)Maven学习-处理资源文件
转自:http://www.cnblogs.com/now-fighting/p/4888343.html 在前面两篇文章中,我们学习了Maven的基本使用方式和Maven项目的标准目录结构.接下来, ...