LinkedList源码详解

    public class LinkedList<E>extends AbstractSequentialList<E>implements List<E>, Deque<E>, Cloneable, java.io.Serializable

LinkedList继承自AbstractSequenceList、实现了List及Deque接口。
AbstractSequenceList提供List接口的骨干实现,以减少实现List接口的复杂度。
Deque是Queue的一个子接口,双向队列是指该队列两端的元素既能入队(offer)也能出队(poll)。

  • LinkedList的属性
transient int size = 0;             //存储元素的个数
transient Node<E> first;            //头节点                //jdk1.6 Entry<E> header = new Entry<E>(null, null, null);
transient Node<E> last;             //尾节点   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;}}             
  • LinkedList的构造方法
    public LinkedList() {                                   //jdk1.6 header.next = header.previous = header;带有头结点双向循环链表}                                                       //jkd1.7+ 不带头节点的双向链表public LinkedList(Collection<? extends E> c) {this();addAll(c);                                      //conllection 转换成数组 for循环添加}
  • LinkedList的方法
    add方法
   public boolean add(E e) {linkLast(e);                                //直接添加到尾部return true;}public void add(int index, E element) {checkPositionIndex(index);                  //检查下标if (index == size)linkLast(element);                      //是在尾部添加else                                        //中间插入linkBefore(element, node(index));       //查找index处的节点,把新节点添加到它的前面}private void checkPositionIndex(int index) {if (!isPositionIndex(index))                //非真就抛异常throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private boolean isPositionIndex(int index) {return index >= 0 && index <= size;         //当于等于0且小于等于当前size的大小}void linkLast(E e) {                                //分2种情况解释   第一次添加                     非第一次添加final Node<E> l = last;                         //第一次添加last为null                          第二次添加last不是null    final Node<E> newNode = new Node<>(l, e, null); //假如第一次添加个String类型的“1”                第二次添加个String类型的“2”last = newNode;                             //newNode的item是“1”,newNode.next=null         newNode的item是“2”,newNode.next=null if (l == null)                                  //nowNode.prev=null,并将成员变量last指向newNode  nowNode.prev="1"first = newNode;                            //因为是第一次添加,l也是null,                   第二次添加,l不是nullelse                                        //将成员变量frist指向newNode                     将当前添加的节点指向上一个节点的next属性l.next = newNode;                           //添加后是[null]["1"][null]                      [null]["1"]["2"][null]size++;                                         //        prve item next                               prve item nextmodCount++;}void linkBefore(E e, Node<E> succ) {// assert succ != null;final Node<E> pred = succ.prev;                         //获取succ前面的一个节点final Node<E> newNode = new Node<>(pred, e, succ);      //新建一个节点,前面指向succ前面一个借点,后面指向succsucc.prev = newNode;                                    //succ前面的节点指向新建的节点if (pred == null)                                       //如果succ前面的节点为空,新建的节点则为头节点first = newNode;elsepred.next = newNode;                                //否则就将前面节点的下一点指向新建的节点size++;modCount++;}

remove方法

    public boolean remove(Object o) {                           //判断要删除的元素是不是nullif (o == null) {                                        //从首节点开始循环,然后删除for (Node<E> x = first; x != null; x = x.next) {if (x.item == null) {unlink(x);return true;}}} else {for (Node<E> x = first; x != null; x = x.next) {if (o.equals(x.item)) {unlink(x);return true;}}}return false;}public E remove(int index) {checkElementIndex(index);                               //检查数组下标越界return unlink(node(index));}private void checkElementIndex(int index) {if (!isElementIndex(index))throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private boolean isElementIndex(int index) {return index >= 0 && index < size;}Node<E> node(int index) {// assert isElementIndex(index);if (index < (size >> 1)) {                  //假如index小于size的一半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;}}E unlink(Node<E> x) {// assert x != null;                    //假如LinkerList有这么一组数据[1,2,3,4,5] remove index是0的数据final E element = x.item;               //则节点是1 x.item = 1 next  = 2 prev = 3                final Node<E> next = x.next;final Node<E> prev = x.prev;if (prev == null) {                     //prev ==null,2现在就是首节点了first = next;                       //这里要注意一点,假如有这么一组数据[1,2,3,null,null,null,8,9],remove index是4} else {                                //item prve next 分别为空 ,只是表示指向的内容是nullprev.next = next;                   //假如删除的不是头结点,将下个节点指向上个节点的下个节点x.prev = null;                      //将删除的节点的上个节点指向设置为null}if (next == null) {                     last = prev;} else {                                 //接着[1,2,3,4,5]来解释next.prev = prev;                    //假如删除的不是尾结点,prve此时是null了,2是首节点,2.prev = null;x.next = null;                       //将删除的节点的下个节点指向设置为null}x.item = null;                           //将删除的节点也置为nullsize--;modCount++;return element;}

set

     public E set(int index, E element) {checkElementIndex(index);               //检查数据下标越界Node<E> x = node(index);                //获取要修改坐标的元素E oldVal = x.item;                      //获取这个坐标元素的item属性x.item = element;                       //将要修改元素的item属性引用指向elementreturn oldVal;}

get

    public E get(int index) {checkElementIndex(index);               //检查数据下标越界return node(index).item;                //for循环来取}

Iterator

    private class ListItr implements ListIterator<E> {              //正序迭代private Node<E> lastReturned = null;private Node<E> next;private int nextIndex;private int expectedModCount = modCount;ListItr(int index) {next = (index == size) ? null : node(index);nextIndex = index;}public boolean hasNext() {return nextIndex < size;}public E next() {checkForComodification();if (!hasNext())throw new NoSuchElementException();lastReturned = next;next = next.next;nextIndex++;return lastReturned.item;}public boolean hasPrevious() {return nextIndex > 0;}public E previous() {checkForComodification();if (!hasPrevious())throw new NoSuchElementException();lastReturned = next = (next == null) ? last : next.prev;nextIndex--;return lastReturned.item;}public int nextIndex() {return nextIndex;}public int previousIndex() {return nextIndex - 1;}public void remove() {checkForComodification();if (lastReturned == null)throw new IllegalStateException();Node<E> lastNext = lastReturned.next;unlink(lastReturned);if (next == lastReturned)next = lastNext;elsenextIndex--;lastReturned = null;expectedModCount++;}public void set(E e) {if (lastReturned == null)throw new IllegalStateException();checkForComodification();lastReturned.item = e;}public void add(E e) {checkForComodification();lastReturned = null;if (next == null)linkLast(e);elselinkBefore(e, next);nextIndex++;expectedModCount++;}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}}private class DescendingIterator implements Iterator<E> {           //倒序迭代private final ListItr itr = new ListItr(size());public boolean hasNext() {return itr.hasPrevious();}public E next() {return itr.previous();}public void remove() {itr.remove();}}

总结

linkedList基于双向链表实现,有序,允许为null,没有固定容量,不需要扩容。
其中的每个对象包含数据的同时还包含指向链表中前一个与后一个元素的引用。

转载于:https://www.cnblogs.com/Ch1nYK/p/8589415.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/486645.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

arduino uno r3单片机封装图_Arduino教程 | 初识Arduino

前一段时间偶然进入创客空间并接触到了开源硬件&#xff0c;小编表示十分感兴趣。于是这周打算汇总一下网络上现有的一些关于Arduino的及教程进行分享。首先感谢一下各位原作者&#xff0c;在此表示十分感谢~什么是Arduino&#xff1f;Arduino是一个能够用来感应和控制现实物理…

神经网络原来是这样和数学挂钩的

来源&#xff1a;遇见数学近几年&#xff0c;有几个被媒体大肆报道的事件&#xff0c;如下表所示。如上所示&#xff0c;深度学习作为人工智能的一种具有代表性的实现方法&#xff0c;取得了很大的成功。那么&#xff0c;深度学习究竟是什么技术呢&#xff1f;深度学习里的“学…

鸿蒙os开发小程序,9岁小学生展示鸿蒙OS开发:这操作太秀了

华为的鸿蒙 OS 正在迅速成熟&#xff0c;这背后离不开无数开发者的支持。近日&#xff0c;鸿蒙 OS 技术社区就向大家介绍了一位特殊的鸿蒙开发者&#xff0c;今年只有 9 岁&#xff0c;还是个小学生 ……在鸿蒙社区&#xff0c;这位小开发者坐在镜头前&#xff0c;向大家演示了…

python 列表推导式

列表推导式的格式&#xff1a; [表达式 for 变量 in 列表] 或者 [表达式 for 变量 in 列表 if 条件] 举例&#xff1a; #!/usr/bin/python # -*- coding: utf-8 -*-li [1,2,3,4,5,6,7,8,9] print [x**2 for x in li]print [x**2 for x in li if x>5]print dict([(x,x*10) …

java调用一个方法后怎么继续执行不等待该方法的返回_Java面试题大全2020版(二)...

今天给大家推送第二部分&#xff0c;主要的大块内容分为&#xff1a;多线程、反射、对象拷贝。三大块内容中涉及到的考点如下&#xff1a;三、多线程35. 并行和并发有什么区别&#xff1f;并行是指两个或者多个事件在同一时刻发生&#xff1b;而并发是指两个或多个事件在同一时…

城市“脑梗” 当前城市大脑面临的困境

来源&#xff1a;中国建设报智慧城市 作者 刘锋 吕本富2020年&#xff0c;城市大脑已经成为前沿科技和城市建设发展的重点&#xff0c;有近百个城市宣布开展城市大脑建设。数百家科技企业进入到泛城市大脑的建设领域&#xff0c;有数百亿的资金投入到城市大脑的建设中。面对…

html5 banner特效,HTML5特效库 CSS3遮罩banner动画特效源码

效果图各位朋友。大家早上好&#xff01;今天给大家带来的是 CSS3遮罩banner动画特效源码&#xff01;看倦的轮播图的&#xff0c;可以试试这个特效&#xff01;别有一番意思&#xff01;大家可以按照自己的意愿进行行修改&#xff0c;改成自己喜欢的样子&#xff01;有想要文件…

redis和memcached相比的独特之处

1&#xff1a;redis可以用来做存储&#xff08;storge&#xff09;&#xff0c;主要是因为有“持久化”功能&#xff0c;而memcached是用来缓存&#xff08;cache&#xff0c;缓解查询压力&#xff09; 2&#xff1a;存储结构&#xff1a;对于memcached&#xff0c;只有一种类型…

android蓝牙通信_使用Arduino构建OLED显示屏与Android手机接口的智能手表

背景知识视频教程Arduino 训练营&#xff1a;通过项目学习​viadean.com通过制作Arduino UNO FM收音机接收器学习Arduino I2C​viadean.com通过构建实际应用程序来掌握Arduino - 国外课栈​viadean.com我们大多数人都熟悉162点阵液晶显示器&#xff0c;它在许多项目中用于向用户…

DeepMind新突破!首次用深度学习从第一性原理计算分子能量

来源&#xff1a;AI科技评论编译 | 青暮DeepMind发表了一项新研究&#xff0c;展示了深度学习如何帮助解决现实系统中的量子力学基本方程问题&#xff0c;相关论文发表在物理学期刊《Physical Review Research》&#xff0c;代码也已经开源。这种新的神经网络架构叫做Fermionic…

html5离线储存不足,html5的离线存储问题

HTML5的一个重要特性就是离线存储&#xff0c;所谓的离线存储就是将一些资源文件保存在本地&#xff0c;这样后续的页面重新加载将使用本地资源文件&#xff0c;在离线情况下可以继续访问web应用&#xff0c;同时通过一定的手法(更新相关文件或者使用相关API)&#xff0c;可以更…

centos 账号安全设置

1&#xff09;配置文件 /etc/login.defs 设置密码有效期、长度和密码过期时间参数 PASS_MAX_DAYS 设置用户密码的有效期&#xff08;以天数为单位&#xff09; PASS_MIN_DAYS 是否可修改密码&#xff0c;0表示可修改&#xff0c;非0表示多少天可修改 PASS_MIN_LEN 设置用户密码…

重磅发布:2020全球前沿技术发展趋势报告

来源&#xff1a;科技日报作者&#xff1a;刘垠、操秀英大热的脑机接口、基因编辑等前沿技术发展如何&#xff1f;2020年科技界关注了哪些热点&#xff1f;22日在浦江创新论坛上发布的《全球前沿技术发展趋势报告》带来了答案。《全球前沿技术发展趋势报告》由中国科学技术信息…

400错误是什么原因_499错误是什么?499错误的原因及解决方法

​HTTP状态码出现499错误有多种情况&#xff0c;499错误是什么&#xff1f;下面我们来学习Nginx 499错误的原因及解决方法。日志记录中HTTP状态码出现499错误有多种情况&#xff0c;比如nginx反代到一个永远打不开的后端&#xff0c;日志状态记录就会是499、发送字节数是0。​经…

MapReduce过程详解及其性能优化

http://blog.csdn.net/aijiudu/article/details/72353510 废话不说直接来一张图如下&#xff1a; 从JVM的角度看Map和Reduce Map阶段包括&#xff1a; 第一读数据&#xff1a;从HDFS读取数据 1、问题:读取数据产生多少个Mapper&#xff1f;&#xff1f; Mapper数据过大的话&…

爱因斯坦梦断“大统一理论”

来源&#xff1a;数学职业家爱因斯坦发表了他最为得意之作&#xff1a;广义相对论之后&#xff0c;便开始了他的“统一之梦”。大有“躲进小楼成一统&#xff0c;管他冬夏与春秋”之势&#xff0c;这一“统”就是三十余年&#xff0c;到死方休。尽管统一场论一词始于爱因斯坦&a…

js数组截取前5个_想用好 Node.js?这 5 个经典国产项目值得细品

凭借着高并发性能优秀、异步事件驱动、入门简单等优势&#xff0c;Node.js 受到了不少开发者们的青睐。但不得不承认的是&#xff0c;如果用不好 Node.js&#xff0c;它的坑就会非常多&#xff0c;为了帮助各位 Node.js 的开发者们更灵活地使用它&#xff0c;Gitee 为大家推荐以…

微博html天涯吴奇隆刘诗诗,吴奇隆深夜微博晒爱心,为刘诗诗庆生,网友:撒了一大把狗粮...

导语&#xff1a;吴奇隆深夜微博晒爱心&#xff0c;为刘诗诗庆生&#xff0c;网友&#xff1a;撒了一大把狗粮明星夫妻的甜蜜生活&#xff0c;总会让大家感到幸福浪漫。看到自己的偶像能够过得这么好&#xff0c;作为粉丝心里也是很美的&#xff0c;为偶像的幸福感到高兴。娱乐…

模拟器登陆

Python模拟登录的几种方法 https://www.cnblogs.com/chenxiaohan/p/7654667.html 图文详解Python模拟登录新浪微博流程 http://python.jobbole.com/86638/转载于:https://www.cnblogs.com/zhangbojiangfeng/p/8605114.html

设计模式:单例模式(使用c++分别实现饿汉式单例、带双重检查锁定机制的懒汉式单例以及IoDH技术的单例)

单例模式 引言正文1. 饿汉式单例2. 带双重检查锁定机制的懒汉式单例3. IoDH技术的单例 结论优点饿汉式单例带双重检查锁定机制的懒汉式单例IoDH技术的单例 缺点饿汉式单例带双重检查锁定机制的懒汉式单例IoDH技术的单例 引言 在软件开发中&#xff0c;单例模式是一种很常用的设…