/**
* 数组实现可扩容可复用的队列
*/
class MyArrayQueenTest{
public static void main(String[] args) {
MyArrayQueen<String> queen = new MyArrayQueen<>(3);
queen.offer("a");
queen.offer("b");
queen.offer("c");
System.out.println(queen);
System.out.println(queen.poll());
System.out.println(queen.poll());
queen.offer("d");
System.out.println(queen);
queen.offer("e");
System.out.println(queen);
System.out.println(queen.peek());
}
}
public class MyArrayQueen<T> {
static final int MAX_CAPACITY = Integer.MAX_VALUE-8;
//底层数组和队列元素个数
private Object[] arr;
private int size;
//头指针和尾指针
private int front;
private int rear;
public MyArrayQueen() {
//默认构造,数组长度为10
this.arr = new Object[10];
}
public MyArrayQueen(int initCapacity) {
//如果数组长度非法,抛出异常
if(initCapacity<1||initCapacity>MAX_CAPACITY) throw new IllegalArgumentException("param is illegal");
this.arr = new Object[initCapacity];
}
/**
* 判断队列是否为空
* @return true 空
*/
public boolean isEmpty(){
return size==0;
}
/**
* 向队列中添加元素的方法
* @param t 要添加的元素
* @return true 添加成功
*/
public boolean offer(T t){
//新增元素不能为空
if(t == null) throw new IllegalArgumentException("param is null");
if(isEmpty()){
arr[rear] = t;
size++;
return true;
}
//数组已经满了,先扩容
if(size==arr.length){
int newLen = getLen();
grow(newLen);
}
//添加元素,当数组没满的时候,取模可以让数组可以循环利用
rear = (rear+1)%arr.length;
arr[rear] = t;
size++;
return true;
}
/**
* 队列头部元素出队的方法
* @return 出队的元素
*/
public T poll(){
//队列为空,抛出异常
if(isEmpty()) throw new RuntimeException("queen is empty");
//队列不为空,队头元素出队列,front指针加1取模,可让队列未满进行循环
T value =(T) arr[front];
front = (front+1)%arr.length;
size--;
return value;
}
/**
* 获取队头元素的方法
* @return 队头元素
*/
public T peek(){
//队列为空,抛出异常
if(isEmpty()) throw new RuntimeException("queen is empty");
//队列不为空,返回队头元素
return (T) arr[front];
}
/**
* 数组扩容的私有方法
*
* @param newLen :扩容后数组的长度
*/
private void grow(int newLen) {
//创建新数组
Object[] objects = new Object[newLen];
//转移原来数组的元素到新数组上,
for (int i = 0; i < arr.length; i++) {
int index = (front+i)%arr.length;
objects[i] = arr[index];
}
//让新数组成为当前底层数组
arr = objects;
//将指针位置重置
front = 0;
rear = size-1;
}
/**
* 获取扩容数组长度的私有方法
*
* @return 新数组的长度
*/
private int getLen() {
int oldLen = arr.length;
//如果扩容前数组长度已经为最大值,抛出异常
if (oldLen == MAX_CAPACITY) throw new RuntimeException("Arr is fullMax");
//新数组扩容后的长度等于原来数组长度的两倍
int newLen = (oldLen << 1);
//如果扩容后长度参数溢出或者大于最大数组长度,就让数组扩容为最大长度
if (newLen < 0 || newLen > MAX_CAPACITY) {
newLen = MAX_CAPACITY;
}
return newLen;
}
@Override
public String toString() {
//队列为空,打印"[]"
if(isEmpty()) return "[]";
//队列不为空
StringBuilder s = new StringBuilder();
s.append("[");
//从队头元素开始打印,front开始,打印size个元素
for (int i = front; i < front+size; i++) {
//对应元素的下标应该是:i%arr.length
s.append(arr[i%arr.length]+",");
}
//去掉末尾的逗号
String str = s.toString().substring(0,s.toString().length()-1);
return str+"]";
}
}
09-05
147
12-13
331
03-28
558