Java-链表LinkedList源码原理分析,并且通过LinkedList构建队列
在这里我们介绍一下最简单的链表LinkedList;
看一下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原理就是:
1.首先获取链表最后一个节点。
2.把新节点插入到最后一个节点之后。
3.linkedList的last属性重新指向最后一个节点。
4.如果这个节点是第一个节点,之前没有节点,那么将linkedList的first的属性指向新节点;如果不是,则将上一个节点的next属性指向该节点。
使用LinkedList构建先进先出队列:
offer()方法入队:使用add()方法插入节点在最后。
public boolean offer(E e) {
return add(e);
}
poll()方法出队:从链表表头开始移出队列
public E poll() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
}
使用LinkedList构建后进先出队列:
push()方法入队:插入节点在first
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++;
}
pop()方法出队:从链表表头开始移出队列
public E pop() {
return removeFirst();
}
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}
最后需要注意的是:LinkedList是线程不安全的,如果需要线程安全那么请使用synchronized加锁,或者使用vector,或者使用java.util.concurrent包。
如果需要线程遍历List的时候,避免出现ConcurrentModificationException异常,那么有3种解决方式。
1.遍历List的使用synchronized加锁;
2.使用java.util.concurrent包下面的CopyOnWriteArrayList,每次使用List时实际上都是使用的List副本。
3.使用Jdk8中foreach方法,不过该方法只接受lambda表达式
list.forEach(item -> {
System.out.println("遍历元素:" + item);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Java-链表LinkedList源码原理分析,并且通过LinkedList构建队列的更多相关文章
- Java自定义注解源码+原理解释(使用Java自定义注解校验bean传入参数合法性)
Java自定义注解源码+原理解释(使用Java自定义注解校验bean传入参数合法性) 前言:由于前段时间忙于写接口,在接口中需要做很多的参数校验,本着简洁.高效的原则,便写了这个小工具供自己使用(内容 ...
- Android版数据结构与算法(三):基于链表的实现LinkedList源码彻底分析
版权声明:本文出自汪磊的博客,未经作者允许禁止转载. LinkedList 是一个双向链表.它可以被当作堆栈.队列或双端队列进行操作.LinkedList相对于ArrayList来说,添加,删除元素效 ...
- Java小白集合源码的学习系列:LinkedList
目录 LinkedList 源码学习 LinkedList继承体系 LinkedList核心源码 Deque相关操作 总结 LinkedList 源码学习 前文传送门:Java小白集合源码的学习系列: ...
- HashMap 与 ConcrrentHashMap 使用以及源码原理分析
前奏一:HashMap面试中常见问题汇总 HashMap的工作原理是近年来常见的Java面试题,几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道HashTable和Has ...
- Java小白集合源码的学习系列:Vector
目录 Vector源码学习 Vector继承体系 Vector核心源码 基本属性 构造器 扩容机制 Enumeration 概述 源码描述 具体操作 Vector总结 Vector源码学习 前文传送门 ...
- Java JDK1.8源码学习之路 1 Object
写在最前 对于一个合格的后端程序员来说,现行的流行框架早已经能胜任基本的企业开发,Springboot 任何的框架都把重复的工作更佳简单/优化的解决掉,但是完全陷入在这样的温水里面, 好比温水煮青蛙, ...
- java基础解析系列(十)---ArrayList和LinkedList源码及使用分析
java基础解析系列(十)---ArrayList和LinkedList源码及使用分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder jav ...
- java集合系列之LinkedList源码分析
java集合系列之LinkedList源码分析 LinkedList数据结构简介 LinkedList底层是通过双端双向链表实现的,其基本数据结构如下,每一个节点类为Node对象,每个Node节点包含 ...
- Java入门系列之集合LinkedList源码分析(九)
前言 上一节我们手写实现了单链表和双链表,本节我们来看看源码是如何实现的并且对比手动实现有哪些可优化的地方. LinkedList源码分析 通过上一节我们对双链表原理的讲解,同时我们对照如下图也可知道 ...
随机推荐
- Rails: No such file or directory - getcwd
这个的意思就是你从一个删除的目录里面运行实例:rails s
- AchartEngine绘图引擎
https://code.google.com/p/achartengine/ Code Test代码: /workspace/AChartEngineTest /workspace/appco ...
- Android 中ViewPagerIndicator的使用
1.https://github.com/JakeWharton/Android-ViewPagerIndicator 2.http://blog.csdn.net/xiaanming/article ...
- 自动化测试管理平台ATMS(V2.0.2_8.19)下载
自动化测试管理平台ATMS(V2.0.2_8.19)下载 http://www.automationqa.com/forum.php?mod=viewthread&tid=2791
- swift 方法
swift的类,结构体,枚举中都可以定义方法. 1:实例方法.类似于类成员方法 1.1实例方法是属于类,结构体,枚举的实例的方法.通过其实例访问. class CShow{ func testShow ...
- 说说lambda表达式与表达式树(未完)
Lambda表达式可以转换成为代码(委托)或者数据(表达式树).若将其赋值给委托,则Lambda表达式将转换为IL代码:如果赋值给 Expression<TDelegate>,则构造出一颗 ...
- JAVA笔记 之 Thread线程
线程是一个程序的多个执行路径,执行调度的单位,依托于进程存在. 线程不仅可以共享进程的内存,而且还拥有一个属于自己的内存空间,这段内存空间也叫做线程栈,是在建立线程时由系统分配的,主要用来保存线程内部 ...
- DMSFrame 之SqlCacheDependency(二)
上篇文章介绍的是通知模式的缓存机制,这里介绍的是数据库轮循模式处理,这种模式对SQL2005以下的支持还是比较好的 引擎源码如下: /// <summary> /// 轮循模式 /// 数 ...
- JDBC连接SQL Server2008
在使用JDBC连接数据库之前首先要加载相应数据库的JDBC驱动类,可以通过通用方法Class.forName来加载驱动类. 方式一:使用JDBC-ODBC连接桥 一般安装JDK后会自带JDBC-O ...
- Maven更新子模块的版本号
mark! 已写成了另一篇,不要打我.