jdk1.8-ArrayDeque

public class ArrayDeque<E> extends AbstractCollection<E>
implements Deque<E>, Cloneable, Serializable
/**
* The array in which the elements of the deque are stored.
* The capacity of the deque is the length of this array, which is
* always a power of two. The array is never allowed to become
* full, except transiently within an addX method where it is
* resized (see doubleCapacity) immediately upon becoming full,
* thus avoiding head and tail wrapping around to equal each
* other. We also guarantee that all array cells not holding
* deque elements are always null.
*
* 存放元素的Object[]数组(底层数据结构)
*/
transient Object[] elements; // non-private to simplify nested class access
/**
* The index of the element at the head of the deque (which is the
* element that would be removed by remove() or pop()); or an
* arbitrary number equal to tail if the deque is empty.
*
* 队首元素所在位置
*/
transient int head;
/**
* The index at which the next element would be added to the tail
* of the deque (via addLast(E), add(E), or push(E)).
*
* 队尾元素所在位置
*/
transient int tail;
/**
* The minimum capacity that we'll use for a newly created deque.
* Must be a power of 2.
*
* 容量最小值,2的次幂,默认为8
*/
private static final int MIN_INITIAL_CAPACITY = 8;
/**
* Allocates empty array to hold the given number of elements.
*
* @param numElements the number of elements to hold
*
* 寻找numElements的最近的二次幂值initialCapacity
* new一个长度为initialCapacity的新Object[]数组
*/
private void allocateElements(int numElements) {
int initialCapacity = MIN_INITIAL_CAPACITY;
// Find the best power of two to hold elements.
// Tests "<=" because arrays aren't kept full.
if (numElements >= initialCapacity) {
initialCapacity = numElements;
initialCapacity |= (initialCapacity >>> 1);
initialCapacity |= (initialCapacity >>> 2);
initialCapacity |= (initialCapacity >>> 4);
initialCapacity |= (initialCapacity >>> 8);
initialCapacity |= (initialCapacity >>> 16);
initialCapacity++;
if (initialCapacity < 0) // Too many elements, must back off
initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
}
elements = new Object[initialCapacity];
}
分析:这个计算方法参考下面这个链接,讲的挺好
/**
* Constructs an empty array deque with an initial capacity
* sufficient to hold 16 elements.
*
* 无参构造函数初始化数组长度为16
*/
public ArrayDeque() {
elements = new Object[16];
}
/**
* Constructs an empty array deque with an initial capacity
* sufficient to hold the specified number of elements.
*
* @param numElements lower bound on initial capacity of the deque
*
* 传入长度,构造函数
*/
public ArrayDeque(int numElements) {
allocateElements(numElements);
}
分析:传入长度,初始为数组长度为大于等于numElements最小2次幂
/**
* Constructs a deque containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator. (The first element returned by the collection's
* iterator becomes the first element, or <i>front</i> of the
* deque.)
*
* @param c the collection whose elements are to be placed into the deque
* @throws NullPointerException if the specified collection is null
*
* 传入集合,构造函数
*/
public ArrayDeque(Collection<? extends E> c) {
allocateElements(c.size());
addAll(c);
}
分析:初始化数组长度为大于等于集合长度的最小2次幂,调用addAll()方法
/**
* {@inheritDoc}
*
* <p>This implementation iterates over the specified collection, and adds
* each object returned by the iterator to this collection, in turn.
*
* <p>Note that this implementation will throw an
* <tt>UnsupportedOperationException</tt> unless <tt>add</tt> is
* overridden (assuming the specified collection is non-empty).
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IllegalStateException {@inheritDoc}
*
* @see #add(Object)
*/
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
分析:遍历集合,一个个add添加
/**
* Inserts the specified element at the end of this deque.
*
* @param e the element to add
* @return {@code true} (as specified by {@link Deque#offerLast})
* @throws NullPointerException if the specified element is null
*
* 添加到队尾
*/
public boolean offerLast(E e) {
addLast(e);
return true;
}
分析:传入元素,调用addLast()方法
/**
* Inserts the specified element at the end of this deque.
*
* <p>This method is equivalent to {@link #add}.
*
* @param e the element to add
* @throws NullPointerException if the specified element is null
*
*/
public void addLast(E e) {
//判空
if (e == null)
throw new NullPointerException();
//根据下标,队尾值为e
elements[tail] = e;
if ( (tail = (tail + 1) & (elements.length - 1)) == head)
doubleCapacity();
}
分析:这里直接在队尾里添加了元素e,因为ArrayDeque是一个循环队列,所以当队尾和队头重合说明,队列满了,需要进行扩容。
tail = (tail + 1) & (elements.length - 1)) == head

public void addFirst(E e) {
if (e == null)
throw new NullPointerException();
elements[head = (head - 1) & (elements.length - 1)] = e;
if (head == tail)
doubleCapacity();
}
/**
* Doubles the capacity of this deque. Call only when full, i.e.,
* when head and tail have wrapped around to become equal.
*/
private void doubleCapacity() {
//断言头和尾是不是重,也就是队列是否满了
assert head == tail;
//头部索引p
int p = head;
//队列长度n
int n = elements.length;
//头部元素右边有多少个元素r包括头部
int r = n - p; // number of elements to the right of p
//队列长度扩大为2倍
int newCapacity = n << 1;
//如果扩大两倍后长度超过了int大小变为负数,则抛错
if (newCapacity < 0)
throw new IllegalStateException("Sorry, deque too big");
//new一个新的数组长度为原来的两倍
Object[] a = new Object[newCapacity];
//旧数组elements 从p头部开始, 新数组a,从0开始, 长度为r。所以是拷贝原数组p右侧数据包括p
System.arraycopy(elements, p, a, 0, r);
//旧数组elements 从下标0开始, 新数组a,从下标r开始, 长度为p。所以是拷贝原数组p左侧数据
System.arraycopy(elements, 0, a, r, p);
//旧数组等于新数组a
elements = a;
//队头索引等于0
head = 0;
//队尾索引等于n,n为旧数组的长度不是最新的数组
tail = n;
}
分析:这里看上面的注释已经将得很清晰了,但是我们这里需要注意一个问题


public E pollFirst() {
//头部索引等于h
int h = head;
@SuppressWarnings("unchecked")
//检查头部是否有元素
E result = (E) elements[h];
// Element is null if deque empty
if (result == null)
return null;
//令当前位置为null
elements[h] = null; // Must null out slot
//队头索引向递增方向退一位
head = (h + 1) & (elements.length - 1);
return result;
}

jdk1.8-ArrayDeque的更多相关文章
- 给jdk写注释系列之jdk1.6容器(11)-Queue之ArrayDeque源码解析
前面讲了Stack是一种先进后出的数据结构:栈,那么对应的Queue是一种先进先出(First In First Out)的数据结构:队列. 对比一下Stack,Queue是一种先进先出的容 ...
- 学习JDK1.8集合源码之--ArrayDeque
1. ArrayDeque简介 ArrayDeque是基于数组实现的一种双端队列,既可以当成普通的队列用(先进先出),也可以当成栈来用(后进先出),故ArrayDeque完全可以代替Stack,Arr ...
- 给jdk写注释系列之jdk1.6容器(13)-总结篇之Java集合与数据结构
是的,这篇blogs是一个总结篇,最开始的时候我提到过,对于java容器或集合的学习也可以看做是对数据结构的学习与应用.在前面我们分析了很多的java容器,也接触了好多种常用的数据结构,今天 ...
- 给jdk写注释系列之jdk1.6容器(12)-PriorityQueue源码解析
PriorityQueue是一种什么样的容器呢?看过前面的几个jdk容器分析的话,看到Queue这个单词你一定会,哦~这是一种队列.是的,PriorityQueue是一种队列,但是它又是一种什么样的队 ...
- JDK1.8源码阅读系列之三:Vector
本篇随笔主要描述的是我阅读 Vector 源码期间的对于 Vector 的一些实现上的个人理解,用于个人备忘,有不对的地方,请指出- 先来看一下 Vector 的继承图: 可以看出,Vector 的直 ...
- jdk1.8.0_45源码解读——Set接口和AbstractSet抽象类的实现
jdk1.8.0_45源码解读——Set接口和AbstractSet抽象类的实现 一. Set架构 如上图: (01) Set 是继承于Collection的接口.它是一个不允许有重复元素的集合.(0 ...
- JDK7集合框架源码阅读(七) ArrayDeque
基于版本jdk1.7.0_80 java.util.ArrayDeque 代码如下 /* * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to li ...
- 【Java源码】集合类-ArrayDeque
一.类继承关系 ArrayDeque和LinkedList一样都实现了双端队列Deque接口,但它们内部的数据结构和使用方法却不一样.根据该类的源码注释翻译可知: ArrayDeque实现了Deque ...
- 【集合系列】- 深入浅出分析 ArrayDeque
一.摘要 在 jdk1.5 中,新增了 Queue 接口,代表一种队列集合的实现,咱们继续来聊聊 java 集合体系中的 Queue 接口. Queue 接口是由大名鼎鼎的 Doug Lea 创建,中 ...
- 学习JDK1.8集合源码之--HashMap
1. HashMap简介 HashMap是一种key-value结构存储数据的集合,是map集合的经典哈希实现. HashMap允许存储null键和null值,但null键最多只能有一个(HashSe ...
随机推荐
- Scrapy爬取小说简单逻辑
Scrapy爬取小说简单逻辑 一 准备工作 1)安装Python 2)安装PIP 3)安装scrapy 4)安装pywin32 5)安装VCForPython27.exe ........... 具体 ...
- Redis 配置连接池,redisTemplate 操作多个db数据库,切换多个db,解决JedisConnectionFactory的设置连接方法过时问题。(转)
环境 springmvc jdk1.8 maven redis.properties配置文件 #redis setting redis.host=localhost redis.port=6379 r ...
- 基于LVM 测试磁盘写性能.md
准备工作 /dev/sdb 创建一个卷组,基于卷组创建5个逻辑卷,各100G 在10.10.88.214 新建5台虚拟机,每台虚拟机用到lvm建的逻辑卷 dd 压测 在每台虚拟机上执行dd 命令: d ...
- Autel MaxiIM IM608:如何更新和一些评论
MaxiIM IM608是最先进的,因此是与众不同的一种钥匙编程和诊断工具,它将先进的钥匙编程,所有系统医学和先进的服务融合在一个主要基于10.1英寸触摸屏的机械人中.它配备了XP400关键计算机用户 ...
- 35. ClustrixDB 减少device1大小
ClustrixDB中的device1文件用于所有数据库数据.撤消日志.临时表.binlog和ClustrixDB系统对象.ClustrixDB确保device1文件在集群的所有节点上大小相同.一旦得 ...
- 利用栈实现字符串中三种括号的匹配问题c++语言实现
编写一个算法,检查一个程序中的花括号,方括号和圆括号是否配对,若能够全部配对则返回1,否则返回0. Head.h: #ifndef HEAD_H_INCLUDED #define HEAD_H_INC ...
- nginx配置跨域问题
1.跨域指的是浏览器不能执行其它网站的脚本,它是由浏览器的同源策略造成的,是浏览器对JavaScript 施加的安全限制. 2.浏览器在执行脚本的时候,都会检查这个脚本属于哪个页面,即检查是否同源,只 ...
- Vue 新手学习笔记:vue-element-admin 之安装,配置及入门开发
所属专栏: Vue 开发学习进步 说实话都是逼出来的,对于前端没干过ES6都不会的人,vue视频也就看了基础的一些但没办法,接下来做微服务架构,前端就用 vue,这块你负责....说多了都是泪,脚手架 ...
- 微信小程序_(校园视)开发视频的展示页_上
微信小程序_(校园视) 开发用户注册登陆 传送门 微信小程序_(校园视) 开发上传视频业务 传送门 微信小程序_(校园视) 开发视频的展示页-上 传送门 微信小程序_(校园视) 开发视频的展示页-下 ...
- PHP-windows下安装
下载 Apache下载地址:http://httpd.apache.org/download.cgi PHP下载地址:http://php.net/downloads.php 解压 解压到安装路径下H ...