【复习】Java中常见的几种队列

【复习】Java中常见的几种队列

前言

本文不讲具体结构,只粗略讲解如何使用

经常看看、防止遗忘

代码

/**
 * @Author if
 * @Description: 【复习】Java中常见的几种队列
 * @Date 2022-02-25 下午 07:12
 */
public class QueueTest {
    public static void main(String[] args) {
        /**
         * 普通队列,默认0容量
         * 所有类型的Queue队列都拥有add与remove会抛异常,offer与poll不抛异常的特点
         */
        Queue<Integer> queue=new LinkedList<>();
        //元素入队出队,失败的时候会抛出异常(不推荐)
        queue.add(2);
        System.out.println("queue.remove() = " + queue.remove());
        //元素入队出队,失败的时候不会抛出异常(推荐)
        queue.offer(1);
        System.out.println("queue.poll() = " + queue.poll());

        /** 
         * 双端队列,ArrayDeque容量默认16,LinkedList容量默认0
         */
        Deque<Integer> arrayDeque = new ArrayDeque<>();
        Deque<Integer> linkedList = new LinkedList<>();
        //元素添加到队首
        arrayDeque.offerFirst(3);
        arrayDeque.offerFirst(5);
        arrayDeque.offerFirst(1);
        //输出队首与队尾的元素
        System.out.println("arrayDeque.pollFirst() = " + arrayDeque.pollFirst());
        System.out.println("arrayDeque.pollLast() = " + arrayDeque.pollLast());

        /** 
         * 阻塞队列,ArrayBlockingQueue必须给初始值,LinkedBlockingQueue默认Integer.MAX_VALUE 
         */
        BlockingQueue<Integer> arrayBlockingQueue = new ArrayBlockingQueue<>(5);
        BlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<>();
        //队列空或满时,将抛出异常的添加与删除
        arrayBlockingQueue.add(1);
        arrayBlockingQueue.remove();
        //队列空或满时,不抛异常且有返回值
        arrayBlockingQueue.offer(2);
        arrayBlockingQueue.poll();
        try{
            //队列空或满时,将一直阻塞等待
            arrayBlockingQueue.put(3);
            arrayBlockingQueue.take();
            //队列空或满时,阻塞等待一定时间后会自动放弃等待
            arrayBlockingQueue.offer(4,5,TimeUnit.SECONDS);
            arrayBlockingQueue.poll(5,TimeUnit.SECONDS);
        }catch(Exception e){
            e.printStackTrace();
        }


        /** 
         * 优先队列,默认容量11,默认递增顺序(n1,n2)->n1-n2。这里写的倒序(n1,n2)->n2-n1 
         */
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>((n1,n2)->n2-n1);
        priorityQueue.offer(3);
        priorityQueue.offer(4);
        priorityQueue.offer(2);
        System.out.println("priorityQueue = " + priorityQueue);

        /** 
         * 延时队列,需要一个继承了Delay类并重写了compareTo与getDelay方法的的消息类,并将其添加到队列中 
         */
        DelayQueue<Message> delayQueue = new DelayQueue<>();
        //添加延时消息m1与m2,分别延时3s与5s
        Message m1 = new Message(1, "hello", 3000);
        Message m2 = new Message(2, "world", 5000);
        //将延时消息放到延时队列中
        delayQueue.offer(m1);
        delayQueue.offer(m2);
        //开启线程进行消费
        new Thread(()->{
            int size = delayQueue.size();
            for (int i = size; i > 0; i--) {
                try {
                    Message message = delayQueue.take();
                    System.out.println("message.getBody() = " + message.getBody());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * @Author if
     * @Description: 延迟队列——消息体
     * 实现Delayed接口就是实现两个方法即compareTo 和 getDelay
     * 最重要的就是getDelay方法,这个方法用来判断是否到期
     * @Date 2022-02-25 下午 07:12
     */
    static class Message implements Delayed {
        private int id;
        // 消息内容
        private String body;
        // 延迟时长,这个是必须的属性。因为要按照这个判断延时时长。
        private long executeTime;

        // 自定义实现比较方法返回 1 0 -1三个参数
        @Override
        public int compareTo(Delayed delayed) {
            Message msg = (Message) delayed;
            return Integer.compare(this.id, msg.id);
        }

        // 延迟任务是否到期执行,就是按照这个方法判断,如果返回的是负数则说明到期否则还没到期
        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(this.executeTime - System.nanoTime(), TimeUnit.NANOSECONDS);
        }

        public String getBody() {
            return body;
        }

        public Message(int id, String body, long delayTime) {
            this.id = id;
            this.body = body;
            this.executeTime = TimeUnit.NANOSECONDS.convert(delayTime, TimeUnit.MILLISECONDS) + System.nanoTime();
        }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值