Java之集合(二)ArrayDeque
转载请注明源出处: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的更多相关文章
- Java之集合(二十六)ConcurrentSkipListMap
转载请注明源出处:http://www.cnblogs.com/lighten/p/7542578.html 1.前言 一个可伸缩的并发实现,这个map实现了排序功能,默认使用的是对象自身的compa ...
- Java之集合(二十七)其它集合
转载请注明源出处:http://www.cnblogs.com/lighten/p/7551368.html 1.前言 本章介绍剩余的3个集合类:ConcurrentSkipListSet.CopyO ...
- Java之集合(二十四)ConcurrentLinkedDeque
转载请注明源出处:http://www.cnblogs.com/lighten/p/7517454.html 1.前言 本章介绍并发队列ConcurrentLinkedDeque,这是一个非阻塞,无锁 ...
- Java之集合(二十三)SynchronousQueue
转载请注明源出处:http://www.cnblogs.com/lighten/p/7515729.html 1.前言 本章介绍阻塞队列SynchronousQueue.之前介绍过LinkedTran ...
- Java之集合(二十二)PriorityBlockingQueue
转载请注明源出处:http://www.cnblogs.com/lighten/p/7510799.html 1.前言 本章介绍阻塞队列PriorityBlockingQueue.这是一个无界有序的阻 ...
- Java之集合(二十五)ConcurrentHashMap
转载请注明源出处:http://www.cnblogs.com/lighten/p/7520808.html 1.前言 本章介绍使用的最频繁的并发集合类之一ConcurrentHashMap,之前介绍 ...
- Java之集合(二十一)LinkedTransferQueue
转载请注明源出处:http://www.cnblogs.com/lighten/p/7505355.html 1.前言 本章介绍无界的阻塞队列LinkedTransferQueue,JDK7才提供了这 ...
- Java之集合(二十)LinkedBlockingQueue
转载请注明源出处:http://www.cnblogs.com/lighten/p/7503678.html 1.前言 本章介绍阻塞队列LinkedBlockingQueue,这是一个基于链表的可选长 ...
- JAVA基础-集合(二)
一.Map整体结构体系 Map是集合的另一大派系,与Collection派系不同的是Map集合是以键值对儿的形式存储在集合的.两个键为映射关系,其中第一个键为主键(主键是唯一的不可重复),第二个键为v ...
随机推荐
- Node.js使用MySQL的连接池
使用Nodejs+MySQL肯定比PHP和MySQL的组合更适合做服务器端的开发. 使用Nodejs你会从他的异步行为中获益良多.比如,提升性能,你无须在从已有的MySQL数据库迁移到其他的NoSQL ...
- 常用的SLAM解决方案
ORB SLAM 可以去Github上自己搜索现成的SLAM程序包 在此基础上做优化 视觉SLAM的分类方法:按摄像头的多少分为单目和双目,按是否使用概率方法分为概率法和图法 链接 学习SLAM重要的 ...
- (二分匹配 模板 KM)奔小康赚大钱--hdu--2255
链接: http://acm.hdu.edu.cn/showproblem.php?pid=2255 代码: #include <iostream> #include <cstdio ...
- 我也谈谈.NET程序员工资低
我从2011年下半年预谋转型,2012春季正式转型到iOS,看了<经过本人 6 年.net 工作经验证明 .net 工资确实比 Java 低>这篇文章,一下子有很多感慨. 我不好意思算我干 ...
- [翻译]NUnit---Range and Repeat Attributes(十五)
RangeAttribute (NUnit 2.5) Range特性用于为参数话测试方法的参数的值范围指定一个值,与Random特性一样,NUnit会将每个参数的值组合为一些了测试用例,所以如果为一个 ...
- HTML5+规范:Webview(管理应用窗口界面)
一.知识点 Webview模块管理应用窗口界面,实现多窗口的逻辑控制管理操作.通过plus.webview可获取应用界面管理对象. 1.方法 1.1.all: 获取所有Webview窗口 Array[ ...
- C# 一些代码小结--datGirdView 保存到csv文件
if (dataGridView1.Rows.Count == 0) { MessageBox.Show("No data available!", "Prompt&qu ...
- CSS2.1SPEC:视觉格式化模型之width属性详解(上)
在介绍了包含块之后,CSS2.1标准中介绍了width属性和height属性,这两个属性在我们的页面布局中也发挥着重要的作用.在盒模型中,width和height包围了一个框的内容区域(content ...
- 机器学习、深度学习、和AI算法可以在网络安全中做什么?
本文由 网易云发布. 本文作者:Alexander Polyakov,ERPScan的首席技术官和联合创始人.EAS-SEC总裁,SAP网络安全传播者. 现在已经出现了相当多的文章涉及机器学习及其保 ...
- “全栈2019”Java多线程第二十四章:等待唤醒机制详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...