4.8.4.6 源码
package com.yzh.maven.entity;
import java.util.ConcurrentModificationException;
import java.util.EmptyStackException;
import com.yzh.maven.base.abstracts.MyQueueAbstract;
import com.yzh.maven.base.dao.MyDequeDao;
import com.yzh.maven.base.dao.MyIterator;
import com.yzh.maven.utils.MyArraysUtils;
/**
* @className MyFrontTailArrayDeque
* @description 基于数组实现双端队列
* @author yzh
* @date 2019-04-21
* @param
*/
public class MyFrontTailArrayDeque extends MyQueueAbstract implements MyDequeDao{
/**循环数组*/
private Object[] loopArray = {};
/**队列大小*/
private int size;
/**循环数组初始化容量*/
private static final int INIT_CAPACITY = 16;
/**队列头指针*/
private int front;
/**队列尾指针*/
private int tail;
private int modCount;
public MyFrontTailArrayDeque(){
//初始化数组
loopArray = new Object[INIT_CAPACITY];
}
/***
* @functionName:size
* @description:队列的大小
* @author yzh
* @date 2019-04-13
* @return int
*/
@Override
public int size(){
return size;
}
/////////////////////////////////////queue////////////////////////////////////
/***
* @functionName:add
* @description:实现元素的添加。
* @param e
* @author yzh
* @date 2019-04-13
* @return boolean
*/
public boolean add(E e) {
this.addLast(e);
return true;
}
/***
* @functionName:offer
* @description:用于实现元素的添加。入队成功返回true,否则返回false,即如果队列已满直接返回false,队列未满则直接插入并返回true。
* @param e
* @author yzh
* @date 2019-04-13
* @return boolean
*/
public boolean offer(E e) {
return this.offerLast(e);
}
/***
* @functionName:remove
* @description:方法直接删除队头的元素。
* @author yzh
* @date 2019-04-13
* @return E
*/
public E remove() {
return this.removeLast();
}
/***
* @functionName:poll
* @description:方法取出并删除队头的元素,当队列为空,返回null。
* @author yzh
* @date 2019-04-13
* @return E
*/
public E poll() {
return this.pollLast();
}
/***
* @functionName:peek
* @description:方法直接取出队头的元素,并不删除。
* @author yzh
* @date 2019-04-13
* @return E
*/
public E peek() {
return this.getFirst();
}
/***
* @functionName:isEmpty
* @description:判断队列是否为空
* @author yzh
* @date 2019-04-13
* @return boolean
*/
public boolean isEmpty(){
return size == 0;
}
///////////////////////////////////////deque/////////////////////////////////////
/***
* @functionName:addFirst
* @description:从对头添加元素
* @author yzh
* @date 2019-04-20
* @return
*/
public void addFirst(E e) {
if (e == null){
throw new NullPointerException();
}
//循环数组长度
int loopArrayLen = loopArray.length;
//队列头指针从数组末尾向左移动指针
front = (front - 1 + loopArrayLen) % loopArrayLen;
//添加元素
loopArray[front] = e;
//当头指针与与尾指针重合时作为扩容的条件
if(front == tail){
expectedCapacity(loopArrayLen);
}
modCount++;
size++;
}
/***
* @functionName:expectedCapacity
* @description:循环数组扩容
* @param capacity 数组的当前容量
* @author yzh
* @date 2019-04-20
* @return
*/
private void expectedCapacity(int capacity) {
//队列头
int start = front;
//原数组容量
int oldCapacity = capacity;
//扩容后的容量
int newCapacity = oldCapacity << 1;
Object[] newLoopArray = new Object[newCapacity];
//拷贝front到array.length -1区间的元素
MyArraysUtils.arrayCopy(loopArray, start, newLoopArray, 0, oldCapacity - start);
//拷贝0到tail区间的元素
MyArraysUtils.arrayCopy(loopArray, 0, newLoopArray, oldCapacity - start, start);
loopArray = newLoopArray;
//扩容后队头指针起始值
front = 0;
//扩容后队尾指针起始值
tail = oldCapacity;
}
/***
* @functionName:addLast
* @description:从对尾添加元素
* @author yzh
* @date 2019-04-20
* @return
*/
public void addLast(E e) {
if (e == null){
throw new NullPointerException();
}
//循环数组长度
int loopArrayLen = loopArray.length;
loopArray[tail] = e;
tail = (tail + 1) % loopArrayLen;
//扩容
if(front == tail){
expectedCapacity(loopArrayLen);
}
modCount++;
size++;
}
/***
* @functionName:offerFirst
* @description:从队列的开头实现元素的添加。入队成功返回true
* @author yzh
* @date 2019-04-20
* @return
*/
@Override
public boolean offerFirst(E e) {
addFirst(e);
return true;
}
/***
* @functionName:offerLast
* @description:从队列的末尾实现元素的添加。入队成功返回true
* @author yzh
* @date 2019-04-20
* @return
*/
@Override
public boolean offerLast(E e) {
addLast(e);
return false;
}
/***
* @functionName:removeFirst
* @description:从队头实现元素的删除
* @author yzh
* @date 2019-04-20
* @return
*/
@Override
public E removeFirst() {
//方法取出并删除队头的元素,当队列为空,返回null。
E e = pollFirst();
//如果元素为空,那么抛出空指针异常
if(e == null){
throw new NullPointerException();
}
return e;
}
/***
* @functionName:removeLast
* @description:从队尾实现元素的删除
* @author yzh
* @date 2019-04-20
* @return
*/
@Override
public E removeLast() {
//方法取出并删除队尾的元素,当队列为空,返回null。
E e = pollLast();
//如果元素为空,那么抛出空指针异常
if(e == null){
throw new NullPointerException();
}
return e;
}
/***
* @functionName:pollFirst
* @description:取出并删除队头的元素,当队列为空,返回null
* @author yzh
* @date 2019-04-20
* @return
*/
@SuppressWarnings("unchecked")
public E pollFirst() {
//如果队列为空,那么返回null
if(isEmpty()){
return null;
}
//获取队头元素
E e = (E)loopArray[front];
//置空(删除)队头元素
loopArray[front] = null;
//队头指针向右移动一个位置
int newFront = (front + 1) % loopArray.length;
front = newFront;
modCount++;
size--;
return e;
}
/***
* @functionName:pollLast
* @description:取出并删除队尾的元素,当队列为空,返回null
* @author yzh
* @date 2019-04-20
* @return
*/
@SuppressWarnings("unchecked")
public E pollLast() {
//如果队列为空,那么返回null
if(isEmpty()){
return null;
}
//获取队尾元素的索引
tail = getEndEIndexByTail();
//由于尾指针总是在队尾元素的下一个索引位置上(或者位于loopArray.length - 1索引位置上),因此总是需要先把尾指针移动到最后一个元素的索引位置上,然后再获取即将删除的队尾元素
E e = (E)loopArray[tail];
//置空(删除)队尾元素
loopArray[tail] = null;
modCount++;
size--;
return e;
}
/***
* @functionName:getFirst
* @description:取出但不删除队头的元素,当队列为空,抛出异常
* @author yzh
* @date 2019-04-20
* @return
*/
@SuppressWarnings("unchecked")
@Override
public E getFirst() {
//如果队列为空,那么抛出异常
if(isEmpty()){
throw new RuntimeException("this dueue is null!");
}
return (E)loopArray[front];
}
/***
* @functionName:getLast
* @description:取出但不删除队尾的元素,当队列为空,抛出异常
* @author yzh
* @date 2019-04-20
* @return
*/
@Override
public E getLast() {
//如果队列为空,那么抛出异常
if(isEmpty()){
throw new RuntimeException("this dueue is null!");
}
//获取队尾元素的索引
int tailEIndex = getEndEIndexByTail();
@SuppressWarnings("unchecked")
E e = (E)loopArray[tailEIndex];
return e;
}
/***
* @functionName:getEndEIndexByTail
* @description:通过tail指针获取队尾元素的索引
* @author yzh
* @date 2019-04-20
* @return
*/
private int getEndEIndexByTail() {
int tailEIndex = 0;
int temp = tail;
//如果tail尾指针的索引>0,那么需要将尾指针向左移动一个位置,以便等于元素队尾元素的索引
if(temp > 0){
tailEIndex = (temp - 1) % loopArray.length;
//如果未调用过addLast方法,说明tail = 0,那么就需要将队尾元素的索引为初始化数组的尾部索引位置
//如果未调用过addLast方法,说明tail = 0,那么就需要将尾指针移动到初始化数组的尾部索引位置,此时由于不能将指针移动到值为loopArray.length的索引位置上,所以这里的tail指针无需向左移动一个位置
}else{
tailEIndex = loopArray.length - 1;
}
return tailEIndex;
}
/***
* @functionName:peekFirst
* @description:取出队头的元素,并不删除
* @author yzh
* @date 2019-04-20
* @return
*/
@SuppressWarnings("unchecked")
@Override
public E peekFirst() {
return (E)loopArray[front];
}
/***
* @functionName:peekLast
* @description:取出队尾的元素,并不删除
* @author yzh
* @date 2019-04-20
* @return
*/
@SuppressWarnings("unchecked")
@Override
public E peekLast() {
//获取队尾元素的索引
int tailEIndex = getEndEIndexByTail();
E e = (E)loopArray[tailEIndex];
return (E) e;
}
///////////////////////////////////Stack///////////////////////////////////////
/***
* @functionName:push
* @description:入栈操作
* @author yzh
* @date 2019-04-20
* @return
*/
@Override
public void push(E e) {
this.addLast(e);
}
/***
* @functionName:pop
* @description:出栈操作
* @author yzh
* @date 2019-04-20
* @return E
*/
@Override
public E pop() {
//如果栈空则抛出异常
if (isEmpty()){
throw new EmptyStackException();
}
E e = this.pollLast();
return e;
}
///////////////////////////////////collection//////////////////////////////////////
/***
* @functionName:remove
* @description:删除集合元素
* @param o 目标元素
* @author yzh
* @date 2019-04-20
* @return boolean
*/
@SuppressWarnings("unchecked")
@Override
public boolean remove(Object o) {
if(isEmpty()){
return false;
}
int loopEIndex = 0;
E e = null;
for(int i = front;i iterator() {
return new MyItr();
}
/**
* @className MyItr
* @description 迭代器
* @author yzh
* @date 2019-04-21
*/
private class MyItr implements MyIterator{
//当亲索引
private int curIndex;
//元素游标,可以移动到下一个元素
private int cursor = front;
//用于判断是否使用了迭代的删除方法并初始化为modCount
private int expectedMoCount = modCount;
/**
* @functionName hasNext
* @description 判断迭代器是否还有元素怒
* @author yzh
* @date 2018-12-31
* @param
*/
@Override
public boolean hasNext() {
//当游标(front指针)与tail指针重合时,此时表示队列为空
return cursor != tail;
}
/**
* @functionName next
* @description 获取下一个元素
* @author yzh
* @date 2018-12-31
* @param
*/
@SuppressWarnings("unchecked")
@Override
public E next() {
//1.检查是否使用了迭代器的remove方法,且不能在迭代器中使用外部的add方法
checkUseIteratorFlag();
//2.记录当前元素的索引
cursor = cursor % loopArray.length;
curIndex = cursor;
//3.返回当前元素,且游标移动到下一个元素
return (E) loopArray[cursor++];
}
/**
* @functionName remove
* @description 删除当前元素
* @author yzh
* @date 2019-04-21
* @param
*/
@Override
public void remove() {
//1.检查是否使用了迭代器的remove方法,且不能在迭代器中使用当前list外部的add方法
checkUseIteratorFlag();
//2.删除元素,此时size-1,所以第3步应把cursor-1,因为删除的后一个元素的索引会向前移动一个位置
delete(curIndex);
//3.重新为游标设值,游标回移
cursor = curIndex;
//4.由于调用了remove方法,所以modCount改变了,所以要把expectedMoCount重新赋值
expectedMoCount = modCount;
}
/**
* @functionName checkUseIteratorFlag
* @description 检查是否使用了迭代器的删除方法
* @author yzh
* @date 2019-04-21
* @param
*/
private void checkUseIteratorFlag(){
if(modCount != expectedMoCount){
throw new ConcurrentModificationException();
}
}
}
/***
* @functionName:toString
* @description:重写toString方法
* @author yzh
* @date 2019-04-13
* @return String
*/
@Override
public String toString(){
MyIterator it = this.iterator();
if(isEmpty()){
return "[]";
}
StringBuffer sbf = new StringBuffer();
sbf.append("[");
E e = null;
for(;;){
e = it.next();
if(!it.hasNext()){
return sbf.append(e).append("]").toString();
}
sbf.append(e).append(",");
}
}
/***
* @functionName:toString
* @description:重写toString方法
* @author yzh
* @date 2019-04-13
* @return String
@Override
public String toString(){
if(isEmpty()){
return "[]";
}
int temp = front;
StringBuffer sbf = new StringBuffer();
sbf.append("[");
for(int i = 0;i