使用数组实现一个简单的队列
案例Demo:
package main.java.queue;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
/**
* 队列是一个有序列表,可以用数组或者是链表来实现;
* 队列遵循先入先出的原则,即先存入队列的数据,要先
* 取出,后存入的要后取出。
*/
public class QueueDemo {
public static void main(String[] args) throws Exception {
//使用数组来模拟队列
ArrayQueue arrayQueue = new ArrayQueue(5);
new Thread(()->{
for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName()+"\t 将元素"+ i+ "放入队列");
arrayQueue.addItemToQueue(i);
System.out.println(Thread.currentThread().getName()+"\t"+arrayQueue.toString());
}
},"线程1").start();
Thread.sleep(5);
new Thread(()->{
for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName()+"\t 移除队列元素");
arrayQueue.removeItemToQueue();
System.out.println(Thread.currentThread().getName()+"\t"+arrayQueue.toString());
}
},"线程2").start();
}
}
class ArrayQueue{
//队列大小
private Integer size;
//队列输入指针位置
private AtomicInteger rear = new AtomicInteger(0);
//数组
private volatile Object[] array;
public ArrayQueue(int size) {
this.size = size;
this.array = new Object[this.size];
}
public ArrayQueue(){
this.size = 0;
this.array = new Object[this.size];
}
public boolean addItemToQueue(Object object){
if (isFull()){
System.out.println("队列已满");
return false;
} else if (this.rear.get() <= this.array.length){
this.array[this.rear.get()] = object;
this.rear.getAndIncrement();
return true;
}
return false;
}
public Object pollItemToQueue() {
if (isEmpty()) {
System.out.println("队列为空");
return null;
}
Object object = this.array[0];
updateQueueContent();
return object;
}
public void removeItemToQueue() {
if (isEmpty()) {
System.out.println("队列为空");
return;
}
updateQueueContent();
}
private void updateQueueContent() {
for (int i = 0; i < this.array.length; i++) {
if (i < this.rear.get() - 1){
this.array[i] = this.array[i+1];
} else {
this.array[i] = null;
}
}
this.rear.getAndDecrement();
}
public boolean isEmpty(){
if (0 == this.rear.get()){
return true;
}
return false;
}
public boolean isFull(){
if (this.rear.get() == this.array.length){
return true;
}
return false;
}
@Override
public String toString() {
return "ArrayQueue{" +
"obj=" + Arrays.toString(array) +
'}';
}
}
运行程序:
线程1 将元素1放入队列
线程1 ArrayQueue{obj=[1, null, null, null, null]}
线程1 将元素2放入队列
线程1 ArrayQueue{obj=[1, 2, null, null, null]}
线程1 将元素3放入队列
线程1 ArrayQueue{obj=[1, 2, 3, null, null]}
线程1 将元素4放入队列
线程1 ArrayQueue{obj=[1, 2, 3, 4, null]}
线程1 将元素5放入队列
线程1 ArrayQueue{obj=[1, 2, 3, 4, 5]}
线程1 将元素6放入队列
队列已满
线程1 ArrayQueue{obj=[1, 2, 3, 4, 5]}
线程1 将元素7放入队列
队列已满
线程1 ArrayQueue{obj=[1, 2, 3, 4, 5]}
线程1 将元素8放入队列
队列已满
线程1 ArrayQueue{obj=[1, 2, 3, 4, 5]}
线程1 将元素9放入队列
队列已满
线程1 ArrayQueue{obj=[1, 2, 3, 4, 5]}
线程1 将元素10放入队列
队列已满
线程1 ArrayQueue{obj=[1, 2, 3, 4, 5]}
线程2 移除队列元素
线程2 ArrayQueue{obj=[2, 3, 4, 5, null]}
线程2 移除队列元素
线程2 ArrayQueue{obj=[3, 4, 5, null, null]}
线程2 移除队列元素
线程2 ArrayQueue{obj=[4, 5, null, null, null]}
线程2 移除队列元素
线程2 ArrayQueue{obj=[5, null, null, null, null]}
线程2 移除队列元素
线程2 ArrayQueue{obj=[null, null, null, null, null]}
线程2 移除队列元素
队列为空
线程2 ArrayQueue{obj=[null, null, null, null, null]}
线程2 移除队列元素
队列为空
线程2 ArrayQueue{obj=[null, null, null, null, null]}
线程2 移除队列元素
队列为空
线程2 ArrayQueue{obj=[null, null, null, null, null]}
线程2 移除队列元素
队列为空
线程2 ArrayQueue{obj=[null, null, null, null, null]}
线程2 移除队列元素
队列为空
线程2 ArrayQueue{obj=[null, null, null, null, null]}
我们还可以采用System提供的一个静态方法arraycopy()来实现数组之间的复制。其函数原型是:
@param src 源数组
@param srcPos 源数组的起始位置
@param dest 目标数组
@param destPos 目标数组的起始位置
@param length 复制的长度
public static native void arraycopy(Object src,int srcPos,Object dest, int destPos,int length);
我们可以updateQueueContent()方法修改如下:
private void updateQueueContent() {
this.rear.getAndDecrement();
System.arraycopy(this.array, 1, this.array, 0, this.rear.get());
array[this.rear.get()] = null;
}
这样的话使用数组就实现了一个简单的队列了。