或许你不知道(2):LinkedList

时间:2021-11-05 17:21:22

一,基本的存储结构及数据存取

LinkedList与ArrayList同属List的范畴,ArrayList实现了RandomAccess接口,通过索引随机访问效率较高,而LinkedList提供了直接访问首属的方法,由于链表的不规则性,要找到LinkedList里面的某个元素相对是比较困难的,但只要找它这个元素要对它进行更新操作是比较高效的。这种高效只通过LinkedList的构造方法就可见一斑。

或许你不知道(2):LinkedList

LinkedList用一个内部类Entry来保存数据。Entry有三个重要属性,element,下一元素next,上一元素previous.从构造方法中可以看出,当前的元素即初始化第一个元素

为header,它的下一元素等于它的上一元素等于本身,也就是当前只有一个header,处于初始化状态为空。它奠定了LinkedList存取元素的一个基本特征,每添加一个元素随机分配位置,但必然要指明它相邻位置的元素,如果需要更新,只需要通过next,previous两个属性重新指定到新的元素,即可完成。而不需要像ArrayList一样重新排列复制所有元素。

看一下LinkedList是怎样添加元素的:

或许你不知道(2):LinkedList

首先,调用这两个方法,都会去调用addBefore()方法,然后传入元素和位置,如果是addFirst()则位置为header.next,如果是addLast()则位置为header,从字面上来理解header是头部的意思,怎么会在addLast()时把它当做位置呢?

别急,我们先来看一下addBefor()的实现,如图:

或许你不知道(2):LinkedList

可以清楚的看到,当调用addLast()时,传过来的位置header通过addBefore()调用Entry的构造方法,它指向的是next,也就是说,当前我要加的元素为element,它的next即下一个元素为header即第一个元素,那么它必然就是最后一个元素喽!但是新的问题出来了,如果是addFirst()呢,它传过来的位置为位置为header.next,同样会指向下一个,把header.next作为当前元素,那么header呢?Header在哪里?那它岂不是没有存储东西?通过观察刚开始的构造方法,实例化一个LinkedList的时候,header确实为空,这时长度size为0,然后在对LinkedList进行存取操作的时候,都没有直接对header进行操作。这可以通过Entry类的remove(用户不可以直接调用)得到佐证。如果你要对header进行删除,会报NoSuchElementException()异常,表明根本就没有这个节点元素。如图:

或许你不知道(2):LinkedList

那么LinkedList为什么要设计这么一个header呢?

我的理解有两点。1,LinkedList底层以链表存储数据,不同于数组,在初始化的时候用户得到一个LinkedList的实例,在这之前,它必须得向内存要空间啊,数组由于可以分配连续的空间,因而可以申请预留空间,但链表由于随机的存储方式(总感觉这种表述不科学啊),如果申请太多预留空间造成较大浪费,所以只能一个,即是给header。2,header不存储数据,也不能算是浪费,因为它虽然没数据但通过next和previous相当于前后的指针,为后进的数据提供安身之所,这是LinkedList存储或者叫算法的体现。

事实上,本人觉得LinkedList最精妙最精华的部分就在于这个addBefor()这部分代码。

前边讲到,既然从一开始的header都有指针,那么LinkedList不管存储多少数据,它必然有一个首尾结合类似于圆的指针链。那么它的往哪存放呢?从代码中可以看到,它实际上是在首或者尾(默认add()为尾)的地方,先打破前后的指针,插入这个位置,然后再通过next和previous指向两旁。Remove()方法,与此类似,先打破被删除的元素指针,然后把它设为NULL.

或许你不知道(2):LinkedList

二,关于modCount与Deque<E>

上篇讲过,modCount保存存储集合被修改更新的次数。集合存储数据的载体Entry对象修饰符为transient,它不属于序列化的一部分。在集合迭代的时候需要用modCount来保证此时外部或其它线程不能对它进行更新修改。

LinkedList实现了Deque接口,此接口又继承自Queue接口。对Queue不熟悉,队列的特性是先进先出。LinkedList中提供一些很少使用(至少本人)的方法都要是基于队列的民,如:peek(),poll(),offer()等.

有意思有一个小细节是,当我们基于面向对象多态的思想定义一个LinkedList集合,List<String> link= new LinkedList<String>();发现无法调用上面提到的这些方法,必须使用LinkedList<String> link = new LinkedList<String>()才可以。

先进先出:

或许你不知道(2):LinkedList

或许你不知道(2):LinkedList的更多相关文章

  1. 或许你不知道:ArrayList

    ArrayList 底层以一个transient 线性数组来存储数据,它提供了无参构造方法,和有参构造方法,用户可以通过有参构造方法来初始化长度.如果不传参数,则默认调用无参构造器,数组默认长度为10 ...

  2. Python爬取CSDN博客文章

    0 url :http://blog.csdn.net/youyou1543724847/article/details/52818339Redis一点基础的东西目录 1.基础底层数据结构 2.win ...

  3. 一次发现underscore源码bug的经历以及对学术界『拿来主义』的思考

    事情是如何发生的 最近干了件事情,发现了 underscore 源码的一个 bug.这件事本身并没有什么可说的,但是过程值得我们深思,记录如下,各位看官仁者见仁智者见智. 平时有浏览园区首页文章的习惯 ...

  4. 《FreeSWITCH&colon; VoIP实战》:SIP 模块 - mod&lowbar;sofia

    SIP 模块是 FreeSWITCH 的主要模块,所以,值得拿出专门一章来讲解. 在前几章时里,你肯定见过几次 sofia 这个词,只是或许还不知道是什么意思.是这样的,Sofia-SIP 是由诺基亚 ...

  5. HHVM 是如何提升 PHP 性能的?

    背景 HHVM 是 Facebook 开发的高性能 PHP 虚拟机,宣称比官方的快9倍,我很好奇,于是抽空简单了解了一下,并整理出这篇文章,希望能回答清楚两方面的问题: HHVM 到底靠谱么?是否可以 ...

  6. Css3中的响应式布局的应用

    Media Queries直译过来就是“媒体查询”,在我们平时的Web页面中head部分常看到这样的一段代码: <link href="css/reset.css" rel= ...

  7. &lbrack;置顶&rsqb; EasyMock构建单元测试

    1. 背景 单元测试作为程序的基本保障.很多时候构建测试场景是一件令人头疼的事.因为之前的单元测试都是内部代码引用的,环境自给自足.开发到了一定程度,你不得不到开始调用外部的接口来完成你的功能.而外部 ...

  8. Ubuntu常用软件推荐,图文详细说明及下载

    抛开Windows,其实在任何一款Linux发行版本中,我们都有超级大量的软件来安装,使用.这次的教程,我就以Ubuntu为例,来给大家推荐一些我认为不错的软件 声明: 1.本文提到的全部软件,都在文 ...

  9. 为什么Java大数据是最火爆的编程语言?

    未来10年将是大数据,人工智能爆发的时代,到时将会有大量的企业需要借助大数据,而Java最大的优势就是它在大数据领域的地位,目前很多的大数据架构都是通过Java来完成的. 在这个Android.iOS ...

随机推荐

  1. iOS开发---有用的网址(持续更新)

    http://ios.jobbole.com/88403/     iOS开发之OCR光学识别储蓄卡以及信用卡 http://ios.jobbole.com/87649/      iOS中常用的第三 ...

  2. cocos2dx的lua绑定

    一.cocos2dx对tolua++绑定的修正 A.c对lua回调函数的引用 在使用cocos2dx编写游戏时,我们经常会设置一些回调函数(时钟.菜单选择等).如果采用脚本方式编写游戏的话,这些回调函 ...

  3. 迁移到 Express 4&period;x

    原文地址: http://expressjs.com/migrating-4.html 概览 从 Express 3 到Express 4 是一个巨大的变化,这意味着现存的 Express 3 应用在 ...

  4. SQLSERVER收缩数据库日志

    数据库名为:EKECMS DUMP TRANSACTION EKECMS WITH NO_LOG;BACKUP LOG EKECMS WITH NO_LOG;DBCC SHRINKDATABASE(E ...

  5. 重构HTML改善web应用设计

    本文从良构,有效性,布局三个角度,结合往日项目开发经历, 整理总结重构HTML改善Web应用设计的几点规则和做法.部分参考自<重构HTML改善Web应用设计>. 重构.什么是重构?为什么要 ...

  6. 利用Readability解决网页正文提取问题

    分享: 利用Readability解决网页正文提取问题   做数据抓取和分析的各位亲们, 有没有遇到下面的难题呢? - 如何从各式各样的网页中提取正文!? 虽然可以用SS为各种网站写脚本做解析, 但是 ...

  7. &lbrack;PHP&rsqb;代码执行和生命周期

    PHP代码的执行:1.和大部分程序一样,接收数据,处理数据,输出结果2.编写的代码就是输入的数据,php内核进行处理,返回相应的输出3.php作为业务程序和编译语言的区别就是,php多了一步把用户代码 ...

  8. 12&period;double的int方

    给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. 不要用Math.pow(double,double)哟.效率极其低下,比连成慢好多: 题 ...

  9. Github 提交本地代 到远程 菜鸟 简明教程

    方法1: 1. 右击项目文件夹  Git Bash Here 或   Git clone  Url  远程仓库地址  Directory  本地文件夹 2. 拷贝(新建)项目文件 3. 添加项目文件 ...

  10. java date相关

    public static void getPreDay() throws ParseException{     String dateStr="2013-1-1";     D ...