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源码分析 通过上一节我们对双链表原理的讲解,同时我们对照如下图也可知道 ...
随机推荐
- Gamma校正与线性工作流
1 Gamma校正是什么?8位亮度值x(0-1)经过x^0.45的一个提亮过程. 2 为什么需要Gamma校正 人的眼睛是以非线性方式感知亮度,在自然界中,人感觉到的一半亮度其实只有全部能量的0.2, ...
- android 九宫加密记事本
自己写的超级安全记事本,用PBEWithMD5AndDES加密sqlite内容几乎无法破解, 九宫点密码登录, 支持备份到SDcard,email,network drivers etc. 附件Apk ...
- 【汇总】iOS开发及Xcode使用中遇到的一些报错问题汇总
这里整合下在开发过程中遇到过的一些报错问题和解决办法:(今天开始逐渐增加) Xcode编译错误集锦:http://www.cnblogs.com/ios-wmm/p/3402261.html ...
- is running beyond physical memory limits. Current usage: 2.0 GB of 2 GB physical memory used; 2.6 GB of 40 GB virtual memory used
昨天使用hadoop跑五一的数据,发现报错: Container [pid=,containerID=container_1453101066555_4130018_01_000067] GB phy ...
- myeclipse不编译解决方法
在开发中经常遇到myeclipse不编译的情况,但不同情况的解决方法又不一样,今天同样是遇到此类情况,在网上狂搜,终于找到一篇好文,它囊括了解决这种情况的常用的方法,现在发出来与大家分享.我遇到的情况 ...
- js apply/call/caller/callee/bind使用方法与区别分析
一.call 方法 调用一个对象的一个方法,以另一个对象替换当前对象(其实就是更改对象的内部指针,即改变对象的this指向的内容). Js代码 call([thisObj[,arg1[, arg2[, ...
- 再次讲解js中的回收机制是怎么一回事。
在前几天的一篇闭包文章中我们简单的介绍了一下闭包,但是并没有深入的讲解,因为闭包涉及的知识点比较多,为了能够更好的理解闭包,今天讲解一下关于js中的回收机制. 在初识闭包一文中我说过js中有回收机制这 ...
- MongoDB入门三:MongoDB shell
MongoDB shell MongDB shell是一个功能完备的Javascript解释器,可以运行Javascript程序.也可以用于连接MongoDB服务器,执行脚本,对数据库进行操作.类似于 ...
- [IR] Boolean retrieval
How to build Inverted Index? 1. Token sequence. 2. Sort by terms. 3. Dictionary & Postings code ...
- [Math] Hidden Markov Model
链接:https://www.zhihu.com/question/20962240/answer/33438846 霍金曾经说过,你多写一个公式,就会少一半的读者. 还是用最经典的例子,掷骰子. ...