转载请注明源出处:http://www.cnblogs.com/lighten/p/7283928.html

1.前言

  上章讲解了Java中的集合接口和相关实现抽象类,本章开始介绍一些具体的实现类,第一个介绍的就是继承自抽象类AbstractCollection的实现类ArrayDeque,其同时实现了Deque接口。Queue的结构是一个单端的队列,从一端进另一端出,Deque是一个双端队列。而ArrayDeque是一个使用循环数组实现的双端队列了。双端队列可以实现单端队列的先入先出的方式,也可以实现栈结构的先入后出的方式,使用比较灵活,看具体需求。ArrayDeque是线程非安全的,所以如果需要实现线程安全,就需要自己处理了。

2.实现讲解

2.1 接口

  Deque接口在上章没有讲解,先从这里开始说明。该接口继承了Queue接口,而且由于其是双端队列,所以自然而然有如下接口:

  这些接口看名称也很容易理解,操作首端和尾端对应的add、offer、remove、poll、element、peek这些方法。除了上面的这些接口,还定义了两个接口:push、pop。这两个接口用于当双端队列作为栈的形式使用时的入栈、出栈接口。剩下的一个接口就是descendingIterator接口了,其提供了一个倒序的迭代器。

2.2 ArrayDeque

  循环数组的双端队列实现起来非常简单,里面的数据结构就只有下图:

  一个数组,一个指向头的下标,一个指向尾的下标。就这么一个简单的结构实现了双端队列。值得注意的是数组的大小必须是2n,为何这么做网上说是由于内存的分配是以2的幂指数个页帧为单位进行的,标准的内存分配大小是4K,用2的幂指数为大小分配空间有利于内存管理。可能是由于这个问题,而我更想讲解的是其是如何保证输入的值是2n的。看下面的代码:

  这一段代码乍一看感觉有些莫名其妙,但是正是由于这段代码保证了其分配的数组大小是2n。这段代码所计算的是:输入一个数字X计算X<Y=2n,使这个等式成立时n取最小的时候Y的值,Y就是分配的数组大小了。所以不管你输入多少(超过Java整数范围除外),最终会满足这个公式使得最终分配的结果是2n。上段代码所实现的功能知道了,但是其这么实现的具体原理是什么呢?如下:

  1.要明确2n使用二进制的表现形式如下:0...010...0,中间有一个1,其它的都是0。

  2.根据1的形式,计算使输入任意的X,等式成立的Y。X的二进制形式为????????,是一个未知数,这样如何求得Y呢?方法很简单,找到X最高位为1的位置:那么X就是0..001???,这种形式了。那么所求的Y就是0..010...0,其值就是比X最高位为1再高一位为1,其它位为0的值。

  3.X的最高为1的那一位是未知的,如何求更高一位为1的Y呢?直接求是没有办法的,但是可以通过将X最高位为1后面所有位都变成1,再加1进位的方式办到。就是0..001???变成0.001..1,使用这个+1就会变成所要的Y:0.010...0了。

  4.如何保证X最高位为1后面都是1呢?这个就是上面位运算所实现的内容了。假设X是0..01???,左移一位就是0.001??,做或运算就变成了0..011??,是不是很巧妙,出现了两位为1的就移动2位,获得四位为1的值,这样移动到16的时候就涵盖了32位整数的所有范围了。这个时候+1可能发生整数溢出,所以再左移一位保证在整数范围内。

  以8位整数为例,假设输入的是8:00001000,运算过程如下:

  这样就算出来了结果。循环列表扩容代码如下:

  一个循环数组扩容时,先把队列头右边的放入扩容后的数组,再把队列头左边的内容放入数组后面。

  关于循环数组的操作,其实了解队列的应该也很清楚,就是从头端入就是element[head-1]=Object,从尾端入就是element[tail+1]=Object。出也是对应的,然后就是对head和tail的值进行修改而已,其它的都不难理解,看代码就能清楚了。这里有一个问题就是数组越界的问题,-1或+1都会超过数组的长度,按照循环列表应该定位到数组的尾部或者头部,这里代码中借助了数组长度是2n,解决了这个问题。就是:得到的值 & (elements.length - 1),这样就保证了在数组范围内,且是正确的位置。这个很好理解,不做介绍。

2.3 操作图

  这就是整个添加和扩容的流程了。移除的方法是一样的,就不再画图描述了。

Java之集合(二)ArrayDeque的更多相关文章

  1. Java之集合(二十六)ConcurrentSkipListMap

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7542578.html 1.前言 一个可伸缩的并发实现,这个map实现了排序功能,默认使用的是对象自身的compa ...

  2. Java之集合(二十七)其它集合

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7551368.html 1.前言 本章介绍剩余的3个集合类:ConcurrentSkipListSet.CopyO ...

  3. Java之集合(二十四)ConcurrentLinkedDeque

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7517454.html 1.前言 本章介绍并发队列ConcurrentLinkedDeque,这是一个非阻塞,无锁 ...

  4. Java之集合(二十三)SynchronousQueue

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7515729.html 1.前言 本章介绍阻塞队列SynchronousQueue.之前介绍过LinkedTran ...

  5. Java之集合(二十二)PriorityBlockingQueue

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7510799.html 1.前言 本章介绍阻塞队列PriorityBlockingQueue.这是一个无界有序的阻 ...

  6. Java之集合(二十五)ConcurrentHashMap

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7520808.html 1.前言 本章介绍使用的最频繁的并发集合类之一ConcurrentHashMap,之前介绍 ...

  7. Java之集合(二十一)LinkedTransferQueue

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7505355.html 1.前言 本章介绍无界的阻塞队列LinkedTransferQueue,JDK7才提供了这 ...

  8. Java之集合(二十)LinkedBlockingQueue

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7503678.html 1.前言 本章介绍阻塞队列LinkedBlockingQueue,这是一个基于链表的可选长 ...

  9. JAVA基础-集合(二)

    一.Map整体结构体系 Map是集合的另一大派系,与Collection派系不同的是Map集合是以键值对儿的形式存储在集合的.两个键为映射关系,其中第一个键为主键(主键是唯一的不可重复),第二个键为v ...

随机推荐

  1. 51Nod 1376 最长递增子序列的数量 (DP+BIT)

    题意:略. 析:dp[i] 表示以第 i 个数结尾的LIS的长度和数量,状态方程很好转移,先说长度 dp[i] = max { dp[j] + 1 | a[i] > a[j] && ...

  2. HDU 1513 && POJ 1159 Palindrome (DP+LCS+滚动数组)

    题意:给定一个字符串,让你把它变成回文串,求添加最少的字符数. 析:动态规划是很明显的,就是没有了现思路,还是问的别人才知道,哦,原来要么写,既然是回文串, 那么最后正反都得是一样的,所以我们就正反求 ...

  3. pyhthon lambda

    lambda x:x+1(1) >>>2 可以这样认为,lambda作为一个表达式,定义了一个匿名函数,上例的代码x为入口参数和出口参数,x+1为函数体,(1)为x的入口初始值, 用 ...

  4. Sql Server R8 密码问题及5102错误

    登录的两种方式: 集成登录连接:con = new SqlConnection("server=.\\SQLEXPRESS;database=db_news;Trusted_Connecti ...

  5. EntityFramework 基本模式和Code-First的简单使用

    1.Database-First  Database First就是首先建立好数据库,或者存在现成的数据库也可以.然后在vs中添加ADO.Net实体数据模型,找到需要的数据库和表.它是以数据库设计为基 ...

  6. uploadify的碎碎念 upload

    uploadify是一个jquery插件,用来实现文件上传的功能. 20160724 看起来感觉挺麻烦的 一般会买一个html5版的. html <input id="custom_f ...

  7. Dreamweaver杀手!Illustrator终结者?Flash的末日?图形图像设计程序之网页版

    Dreamweaver杀手!Illustrator终结者?Flash的末日?图形图像设计程序之网页版 阅读:  评论:  作者:Rybby  日期:  来源:rybby.com Adobe 家的 Il ...

  8. Java实现wc部分功能

    GitHub仓库:https://github.com/TaoTaoLv1/WcProject 一.开发前PSP表格预估* PSP2.1 Personal Software Process Stage ...

  9. Android Sms短信发送

    界面布局: 具体代码: private void sendSms() { // 获取电话号码和短信内容 String number = number1.getText().toString(); St ...

  10. java 反射应用

    场景需求最近的一次解析数据包中,因为协议有改变,本来的定长的包,现在变为不定长的.举个例子,本来协议中规定,一个包中,有8个标签,但是每次上来的,不一定都有8个,没有的话,硬件过来的都是0.同时里面也 ...