大家都知道,队列是先进先出的。因此如果我先取出队列头部的单个元素,那么在队列内部会将数组的每个下表向低位移动一位。如果这个队列是百万级别的,那么可以想象到这个性能是多么的蛋疼。让我们换一种思维来解决这个问题:
我将这个数组做成闭环。也就是我取出队列的头元素之后,不移动位置,而是留空。再将原先的第二位元素标记位头元素(下标不动)。如果又有元素进入,则将此元素放入这个数组的空白处。当然如果这个数组还没有填满,则先填满后面的空白,然后再填充通过pop留出的空白元素。
用这种方法,我们就将一个数组做成了一个闭环,不用移动元素的下标也可以做对别的先进先出了,看代码:
package test;
public class Queue {
public static void main(String[] args) {
Queue st = new Queue(100);
for(int i = 0; i < 98; i++) {
st.push(i);
}
System.out.println("pop first=="+st.pop());
st.push(51);
st.push(52);
st.push(53);
while(st.size() > 0) {
Object dt = st.pop();
if(dt != null) {
System.out.println("data="+dt);
}
}
}
private int size = 0;
private int capacity;
private Object[] data;
private int currHead = 0;
private int MAX_SIZE = Integer.MAX_VALUE;
private int currIndex = 0;
public Queue(int capacity) {
data = new Object[capacity];
this.capacity = capacity;
}
public int size() {
return size;
}
public void push(Object obj) {
if(size > MAX_SIZE) {
throw new IllegalArgumentException("over max size....");
}
if(size <= capacity) {
if(currHead == 0) { //如果还没有pop过
data[size++] = obj;
} else{
if(capacity - currHead == size) { //如果队列后面已经满了
data[currIndex++] = obj;
size++;
} else {
data[++size] = obj;
}
}
}
}
public Object pop() {
--size;
if(size >= 0) {
if(currHead == capacity) {
currHead = 0;
}
Object value = data[currHead];
data[currHead] = null;
currHead++;
return value;
}
return null;
}
}