LinkedList 底层实现原理
LinkedList的底层实现原理
LinkedList 底层数据结构为双向链表,链表结构,基于一个个链表节点Node
1,Inner Class 内部类
private static class Node<E>{
E item;//当前节点下的当前元素
Node<E> next;//下一个节点
Node<E> prev;//上一个节点
//constructor
Node(Node<E>prev , E element , Node<E> next){
this.item = element;
this.next = next;
this.prev = prev;
}
}
2,属性 fields
transient size = 0;
transient Node<E> first;
transient Node<E> last;
//LinkedList 底层是链表结构,所以其属性就是封装了链表中一个有多少个节点,以及第一个节点,最后一个节点。
3,构造方法 constructor
//无参构造方法
public LinkedList(){
}
//public LinkedList(Collection <? extends E> c){
this();
addAll(size,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;//pred 代表要有变化的前节点, succ 代表要变化的后节点
例:{“good”,"bad","bye","see","to","two","you","me"} 要实现在index = 2 处insert 一个集合,那么Node<E> prev 就是“bad”所在的节点,Node<E> succ 就是"bye" 所在的节点。
if(index == size){
succ = null;
pred = last;
//按着顺序插入的情况会相等,必须先插入长度为3的集合,然后顺着插入在index 为4 的位置继续插入
}else{
succ = node(index);//-[]-[]-[]-[]-[]/\-[]-[] /\代表插入,succ 后节点就是/\ 之后的节点
pred = succ.prev;
}
//开始插入
for(Object o:a){
@SupressWarnings("unchecked") E e = (E)o;
Node<E> newNode = new Node<>(pred,e,null);
if(pred == null)
first = newNode;
else
pred.next = newNode;
pred = newNode;//为了循环中下一次的赋值,得把pred赋值成当前元素
}
if(succ == null){
last = pred;
}else{
pred.next = succ;
succ.prev = pred;
//因为pred 在for 循环中插入时候一直有更新,所以这段代码的作用是为了将插入的最后一个节点后变化后的节点连接起来,形成一个新的链表。
}
}
//找到即将有变化的节点,这个节点永远是变化的后节点
Node<E> node(int index){
//二分法,如果变化在前半部分,则找出first 如果变化在后半部分,则找出last
if(index < (size >> 1)){//前半部分
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;
}
}
}
private void checkPositionIndex(int index){
if(!isPositionIndex(index))
throw new IndexOutOfBoundsException(OutOfBoundsMsg(index));
}
private boolean isPositionIndex(index){
return index >=0 && index <=size;
}
//addAll(int index,Collection<? extends E> c)这个方法可以用于LinkedList 的初始化中,
可以加载指定集合到目标集合中。
另外,这个方法也可以用于在目标集合指定位置插入指定集合。
4,add
public boolean add(E e){
linkLast(e);
return true;
}
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++;
}
//add方法中范型E控制add元素的类型,如果类型不对,则编译报错,否则不会出现异常。
在最后一个节点后面增加新元素,上一个节点是last,当前是e,下一个null,需要判断当前增加的是不是第一个元素,是则将新增元素赋值为链中的first,不是则将当前元素赋值为last的next元素。
5 addFirst
public void addFirst(E e){
linkFirst(e);
}
private void linkFirst(E e){
Final Node<E> f = first;
Final Node<E> newNode = new Node(null,e,f);
first = newNode;
//每增加一个节点,都要创建和已知节点的关联
if(f == null)
last = newNode;
else
f.prev = newNode;
size++;
modCount++;
}
6,addLast
调用的也是linkLast(E e)方法,和add(E e) 是调用一样的方法,只不过add(E e) 返回类型是boolean 型,addLast是void.
7,removeFirst
public E removeFirst(E e){
final Node<E> f = first;
if(f == null)
throw new NoSuchElementException();
return unLinkFirst(f);
}
privte E unLinkFirst(Node<E> f){
final E element = f.item;
Node<E> next = f.next;
//f 将删除,f的节点关系也需被删除
f.item = null;
f.next = null;
first = next;
if(next == null)
last = next;
else
next.prev = null;
size--;
modCount++;
return element;
}
8,removeLast
public E removeLast(E e){
final Node<E> l = last;
if(last == null)
throw new NoSuchElementException();
return unLinkLast(l);
}
private E unLinkLast(Node<E> l){
final E element = l.item;
fianl Node<E> prev = l.prev;
//clear relationship
l.item = null;
l.prev = null;
//重新设定
last = prev;
if(prev == null)
first = prev;
else
prev.next = null;
size--;
modeCount++:
return element;
}
9,getFirst
public E getFirst(){
fianl Node<E> f = first;
if(f == null)
throw new NoSuchElementException();
return f.item;
}
10,getLast
public E getLast(){
final Node<E> l = last;
if(l == null)
throw new NoSuchElementException();
return l.item;
}
11,查询
public E get(int index){
CheckElementIndex(index);
return node(index).item;//通过node方法获取到当前index 的节点
}
LinkedList 底层实现原理的更多相关文章
- HashMap、LinkedHashMap、ConcurrentHashMap、ArrayList、LinkedList 底层实现
HashMap相关问题 1.你用过HashMap吗?什么是HashMap?你为什么用到它? 用过,HashMap是基于哈希表的Map接口的非同步实现,它允许null键和null值,且HashMap依托 ...
- JDK1.8中LinkedList的实现原理及源码分析
详见:https://blog.csdn.net/cb_lcl/article/details/81222394 一.概述 LinkedList底层是基于双向链表(双向链表的特点, ...
- PHP底层工作原理
最近搭建服务器,突然感觉lamp之间到底是怎么工作的,或者是怎么联系起来?平时只是写程序,重来没有思考过他们之间的工作原理: PHP底层工作原理 图1 php结构 从图上可以看出,php从下到上是一个 ...
- LinkedList底层实现,及其数据结构实现。
LinkedList底层的实现基于双向表 prev data next next指向下一个node的地址.prev指向上一个node. 这里的代码是LinkedList类的源码. private st ...
- Java并发之底层实现原理学习笔记
本篇博文将介绍java并发底层的实现原理,我们知道java实现的并发操作最后肯定是由我们的CPU完成的,中间经历了将java源码编译成.class文件,然后进行加载,然后虚拟机执行引擎进行执行,解释为 ...
- spirng底层实现原理
什么是框架?框架解决的是什么问题? 编程有一个准则,Don't Repeat Yourself(不要重复你的代码),所以我们会将重复的代码抽取出来,封装到方法中:如果封装的方法过多,将将这些方法封装成 ...
- iOS weak底层实现原理
今年年底做了很多决定,离开工作三年的深圳,来到了上海,发现深圳和上海在苹果这方面还是差距有点大的,上海的市场8成使用swift编程,而深圳8成的使用OC,这点还是比较让准备来上海打拼的苹果工程师有点小 ...
- 《Java并发编程的艺术》Java并发机制的底层实现原理(二)
Java并发机制的底层实现原理 1.volatile volatile相当于轻量级的synchronized,在并发编程中保证数据的可见性,使用 valotile 修饰的变量,其内存模型会增加一个 L ...
- Spring(二)IOC底层实现原理
IOC原理 将对象创建交给Spring去管理. 实现IOC的两种方式 IOC配置文件的方式 IOC注解的方式 IOC底层实现原理 底层实现使用的技术 1.1 xml配置文件 1.2 dom4j解析xm ...
随机推荐
- SpringBoot 使用RedisTemplate操作Redis
新版: import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.T ...
- netstat 查看端口
-l 仅列出有在监听(listen)的服务状态 -n 拒绝显示别名,能显示数字的全部转化成数字 -p 显示建立相关链接的程序名 -t 仅显示 tcp 相关选项 -u 仅显示 udp 相关选项 -a 显 ...
- Visual Studio 10.0设置引用HalconDotNet.dll
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u010435562/article/details/8858638 開始做Halcon的上位机.选用 ...
- dxRibbonRadialMenu控件使用
设计视图 双击dxRibbonRadialMenu1增加项目 增改显示文字 增加图标列表 代码很简单,从当前鼠标位置打开,屏蔽系统右键 procedure TForm1.cxMemo1ContextP ...
- Dockerfile语法解析
Dockfile介绍 从上到下依次执行 每次执行一条指令就创建一个镜像层 第一条指令必须是FROM 表示需要构建的镜像是由哪个镜像为基础镜像 后续的指令运行于此基准镜像所提供的运行环境 可以 ...
- 晨枫U盘启动盘制作工具V4.0-安装原版Win7
第一类方法(32位64位系统通用): [1]找到Windows7系统的iso镜像,用UltraISO或者WinRAR打开iso镜像,然后提取/解压所有文件到你的U盘根目录. [2]在你的U盘里找到名为 ...
- C语言编程练习
1.编程序实现求1-1000之间的所有奇数的和并输出. 解法1: int sum=0; for(int i=1;i<=1000;i++){ sum+=i%2?i:0; } printf(&quo ...
- Centos7上安装Apache
Apache HTTP服务器是世界上最流行的Web服务器. 它是一款免费的开源和跨平台的HTTP服务器,提供强大的功能,可以通过各种模块进行扩展. 以下说明介绍如何在CentOS 7机器上安装和管理A ...
- 20165321实验一 Java开发环境的熟悉
一.idea调试: 二.实验内容: 实现学生成绩管理功能(增删改,排序,查找),并进行测试(正常情况,异常情况,边界情况). 运行截图: 代码: public class Student { Stri ...
- iOS 阅读唐巧博客心得
1. iOS 开发中的争议(一) http://blog.devtang.com/2015/03/15/ios-dev-controversy-1/ 文中提及到,在使用的时候,应该是使用self.pr ...