java中Queue的介绍与实现

在Java中,Queue 是一个接口,它属于 java.util 包。Queue 接口继承自 Collection 接口,这意味着它是一个集合,但与普通的集合不同,它遵循先进先出(FIFO)的原则。队列主要用于维护元素的顺序,其中第一个插入的元素将是第一个被移除的。

以下是 Queue 接口的一些关键特性:

  1. 先进先出 (FIFO):队列中的元素按照它们被添加的顺序进行处理。
  2. 头部(Head):队列的第一个元素,它是下一个被移除的元素。
  3. 尾部(Tail):队列的最后一个元素,它是下一个被添加的元素(在某些实现中)。
  4. 容量:一些队列实现有固定容量,而其他实现则可以动态增长。

Queue 接口定义了一些方法,包括:

  • boolean add(E e):将元素添加到队列的尾部。如果成功,返回 true;如果队列满了,抛出 IllegalStateException
  • boolean offer(E e):将元素添加到队列的尾部,如果成功,返回 true;如果队列满了,返回 false,不会抛出异常。
  • E remove():移除并返回队列头部的元素。如果队列为空,抛出 NoSuchElementException
  • E poll():移除并返回队列头部的元素,如果队列为空,返回 null,不会抛出异常。
  • E element():返回队列头部的元素但不移除它。如果队列为空,抛出 NoSuchElementException
  • E peek():返回队列头部的元素但不移除它。如果队列为空,返回 null,不会抛出异常。

Java提供了几种 Queue 的实现:

  1. ArrayDeque:一个双端队列,可以用作栈或队列。
  2. LinkedList:一个链表结构的队列,可以作为队列使用。
  3. PriorityQueue:一个基于优先级的队列,元素根据其自然顺序或者构造时提供的 Comparator 进行排序。
  4. DelayQueue:一个使用优先级队列实现的无界阻塞队列,其中的元素只有在其指定的延迟到期时才能从队列中取走。
  5. ConcurrentLinkedQueue:一个基于链接节点的无界线程安全队列。

使用队列时,你可以根据你的具体需求选择合适的实现。例如,如果你需要一个线程安全的队列,你可能会考虑使用 ConcurrentLinkedQueue。如果你需要一个有固定容量的队列,你可能会使用 ArrayDeque 并设置其容量。

下面提供一些简单的Java代码示例,演示如何使用几种不同的Queue实现。

使用ArrayDeque作为队列

import java.util.ArrayDeque;
import java.util.Queue;

public class ArrayDequeExample {
    public static void main(String[] args) {
        Queue<Integer> queue = new ArrayDeque<>();

        // 添加元素
        queue.add(1);
        queue.add(2);
        queue.add(3);

        // 移除并返回头部元素
        System.out.println(queue.remove()); // 输出 1

        // 查看但不移除头部元素
        System.out.println(queue.peek()); // 输出 2

        // 移除并返回头部元素
        System.out.println(queue.poll()); // 输出 2

        // 添加元素到队列尾部
        queue.offer(4);

        // 查看但不移除头部元素
        System.out.println(queue.element()); // 输出 3

        // 队列中的元素
        System.out.println(queue); // 输出 [3, 4]
    }
}

使用LinkedList作为队列

import java.util.LinkedList;
import java.util.Queue;

public class LinkedListExample {
    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<>();

        // 添加元素
        queue.add(1);
        queue.add(2);
        queue.add(3);

        // 移除并返回头部元素
        System.out.println(queue.remove()); // 输出 1

        // 添加元素到队列尾部
        queue.offer(4);

        // 队列中的元素
        System.out.println(queue); // 输出 [2, 3, 4]
    }
}

使用PriorityQueue作为优先级队列

import java.util.PriorityQueue;

public class PriorityQueueExample {
    public static void main(String[] args) {
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();

        // 添加元素
        priorityQueue.add(5);
        priorityQueue.add(1);
        priorityQueue.add(3);

        // 移除并返回队列中优先级最高的元素(默认是最小的元素)
        System.out.println(priorityQueue.remove()); // 输出 1

        // 队列中的元素
        System.out.println(priorityQueue); // 输出 [3, 5]
    }
}

使用DelayQueue延迟队列

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayQueueExample {
    public static void main(String[] args) throws InterruptedException {
        DelayQueue<MyDelayedObject> delayQueue = new DelayQueue<>();

        // 添加元素到延迟队列
        delayQueue.put(new MyDelayedObject(1, 2, TimeUnit.SECONDS));
        delayQueue.put(new MyDelayedObject(2, 4, TimeUnit.SECONDS));

        // 等待直到元素可用
        MyDelayedObject element1 = delayQueue.take();
        System.out.println("Taken from queue: " + element1); // 2秒后输出 MyDelayedObject{number=1, delay=2}

        MyDelayedObject element2 = delayQueue.take();
        System.out.println("Taken from queue: " + element2); // 4秒后输出 MyDelayedObject{number=2, delay=4}
    }

    static class MyDelayedObject implements Delayed {
        private final int number;
        private final long delay;
        private final long deadline;

        public MyDelayedObject(int number, long delay, TimeUnit timeUnit) {
            this.number = number;
            this.delay = delay;
            this.deadline = System.currentTimeMillis() + timeUnit.toMillis(delay);
        }

        @Override
        public long getDelay(TimeUnit unit) {
            long delay = deadline - System.currentTimeMillis();
            return unit.convert(delay, TimeUnit.MILLISECONDS);
        }

        @Override
        public int compareTo(Delayed other) {
            if (this.deadline < ((MyDelayedObject) other).deadline) {
                return -1;
            }
            if (this.deadline > ((MyDelayedObject) other).deadline) {
                return 1;
            }
            return 0;
        }

        @Override
        public String toString() {
            return "MyDelayedObject{" + "number=" + number + ", delay=" + delay + '}';
        }
    }
}

使用ConcurrentLinkedQueue作为线程安全的队列

import java.util.concurrent.ConcurrentLinkedQueue;

public class ConcurrentLinkedQueueExample {
    public static void main(String[] args) {
        ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<>();

        // 添加元素
        queue.add(1);
        queue.add(2);
        queue.add(3);

        // 移除并返回头部元素
        System.out.println(queue.poll()); // 输出 1

        // 查看但不移除头部元素
        System.out.println(queue.peek()); // 输出 2

        // 队列中的元素
        System.out.println(queue); // 输出 [2, 3]
    }
}

这些示例展示了如何使用不同的队列实现来处理元素的添加、移除和查看操作。可以根据具体需求选择合适的队列实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值