You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java队列实现咨询:如何实现数组的队列式元素移位?

修复你的Java队列实现(实现FIFO逻辑)

嘿,你的这段代码其实是个**栈(LIFO,后进先出)**而非队列!因为dequeue()方法直接从数组末尾取元素,完全是栈的弹出逻辑。要改成真正的队列(FIFO,先进先出),让新元素添加到队尾、移除时取最早加入的元素,甚至在队列满时自动挤出最早元素,我给你两种可行的修改方案:


方案1:简单数组移位(入门易懂)

这个方案逻辑非常直观,适合刚接触队列概念的同学理解核心原理,但缺点是每次出队都要移动数组内的后续元素,数据量较大时效率会偏低(时间复杂度O(n))。

修改要点:

  • 保留enqueue()的逻辑(往数组尾部添加元素,满了自动扩容);
  • 重写dequeue():先取出数组第一个元素(最早加入的元素),再将后续所有元素向前移位一位,最后更新队列大小;
  • 增加空队列判断,避免数组越界报错。

修改后的完整代码:

public class Queue {
    private int[] elements;
    private int size;
    public static final int DefCap = 8;

    public Queue() {
        this(DefCap);
    }

    public Queue(int capacity) {
        elements = new int[capacity];
    }

    public int[] enqueue(int v) {
        if (size >= elements.length) {
            int[] a = new int[elements.length * 2];
            System.arraycopy(elements, 0, a, 0, elements.length);
            elements = a;
        }
        elements[size++] = v;
        return elements;
    }

    public int dequeue() {
        if (empty()) {
            throw new IllegalStateException("Queue is empty");
        }
        // 取出队首的最早元素
        int frontElement = elements[0];
        // 将后续元素整体向前移位一位
        System.arraycopy(elements, 1, elements, 0, size - 1);
        // 清空最后一个位置的冗余值(可选,避免残留旧数据)
        elements[--size] = 0;
        return frontElement;
    }

    public boolean empty() {
        return size == 0;
    }

    public int getSize() {
        return size;
    }
}

方案2:循环数组(环形缓冲区,高效版)

如果需要更高的效率(入队出队均为O(1)时间复杂度),或者要实现固定容量、满队时新元素自动挤出最早元素的逻辑,推荐使用环形缓冲区方案。我们用front指针记录队首位置,rear指针记录队尾的下一个插入位置,通过模运算实现数组空间的循环复用。

修改要点:

  • 新增front和rear两个指针;
  • 入队时:如果队列已满,直接移动front指针(挤出最早元素),再插入新元素;如果未满,正常插入并更新指针;
  • 出队时:直接取front指针位置的元素,再移动front指针更新队首。

修改后的完整代码(固定容量,满队挤最早元素):

public class Queue {
    private int[] elements;
    private int front;
    private int rear;
    private int size;
    public static final int DefCap = 8;

    public Queue() {
        this(DefCap);
    }

    public Queue(int capacity) {
        elements = new int[capacity];
        front = 0;
        rear = 0;
        size = 0;
    }

    // 入队:满队时自动挤出最早加入的元素
    public void enqueue(int v) {
        elements[rear] = v;
        rear = (rear + 1) % elements.length;
        // 队列已满时,移动front指针挤掉最早元素,size保持不变
        if (size == elements.length) {
            front = (front + 1) % elements.length;
        } else {
            size++;
        }
    }

    public int dequeue() {
        if (empty()) {
            throw new IllegalStateException("Queue is empty");
        }
        int frontElement = elements[front];
        front = (front + 1) % elements.length;
        size--;
        return frontElement;
    }

    public boolean empty() {
        return size == 0;
    }

    public int getSize() {
        return size;
    }

    // 可选:获取队列的固定容量
    public int getCapacity() {
        return elements.length;
    }
}

额外说明:

  • 这个版本是固定容量队列,满队后新元素会自动覆盖最早加入的元素;
  • 如果想要保留自动扩容的逻辑,也可以在enqueue()中判断size == elements.length时,扩容数组并重新排列元素,再更新front和rear指针。

测试验证

你可以用以下代码测试两种方案的逻辑:

public static void main(String[] args) {
    Queue queue = new Queue(3); // 用方案2时,小容量更易测试挤元素逻辑
    queue.enqueue(1);
    queue.enqueue(2);
    queue.enqueue(3);
    System.out.println(queue.dequeue()); // 应输出1(最早加入的元素)
    queue.enqueue(4);
    System.out.println(queue.dequeue()); // 应输出2
    System.out.println(queue.dequeue()); // 应输出3
    System.out.println(queue.dequeue()); // 应输出4
}

内容的提问来源于stack exchange,提问作者06ov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 07:02:42