队列Queue、Deque类总结

前言

栈和队列是两种特殊的线性表,是操作受限的线性表,称限定性DS通常称,栈和队列是限定插入和删除只能在表的“端点”进行的线性表

举例:

线性表 Insert(L,i, x) 1<=i<=n+1 Delete(L,i) 1<=i<=n //任意位置插入和删除

栈 Insert(S,n+1,x) Delete(S,n) //同一个口插入和删除

队列 Insert(Q, n+1,x) Delete(Q, 1) //一个口插入,另一个口删除

队列有单向队列(queue)和双向队列(deque)之分

一、Queue类的简介

QueueJava中实现队列的接口,只有6个方法,一般只用其中3个就可以。Queue的实现类有LinkedListPriorityQueue,最常用的实现类是LinkedList

queue允许新增元素、移除元素、从最底端加人元素、从最顶端取出元素。!但除了最底端可以加入、最顶端可以取出外,没有任何其它方法可以存取queue的其它元素。换言之,queue不允许有遍历行为。

将元素推入queue的操作称为push,将元素推出queue的操作称为pop。

定义:队列是限定只能在表的一端进行插入,在表的另一端进行删除的线性表

队尾(rear)一-允许插入的一端

队头(front)--允许删除的一端

特点: 先进先出(FIFO)

1.Queue类方法的使用

1.1 add()与offer()添加元素方法

方法名称

功能描述

boolean add(E e)

插入指定元素为该队列是否有可能立即这样做不违反容量限制

boolean offer(E e)

在不违反容量限制的情况下,将指定的元素插入到队列中

同:未超出容量时,从队尾压入元素,函数返回压入的元素。
异:超出容量时,add(e)方法会抛出异常,offer(e)方法返回null

       //构建队列
       Queue<String> queue = new LinkedList<>();
       //添加元素:add(E e)将元素插入到当前队列中
       queue.add("王大锤"); 
       System.out.println("add以后结果:" + queue);
       //添加元素:offer(E  e)将元素插入到当前队列中
       queue.offer("高圆圆");
       queue.offer("佟丽娅");
       queue.offer("马哥");
       System.out.println("offer以后结果:" + queue);

注意:add(E e)与offer(E e)方法的区别:若操作的队列存在一个大小限制,即队列已经满队时,使用add方法将会抛出unchecked异常添加元素,此时add方法将不再适用,而采用offer方法将返回false,不对程序产生相关影响。

1.2 element()与peek()查看元素方法

方法名称

功能描述

E element()

检索,但不删除此队列的头

E peek()

检索,但不删除,这个队列头,或返回 null如果队列为空

同:容量大于0的时候,都返回队头元素,但是不删除元素。
异:容量为0的时候,element()方法会抛出异常,peek()方法返回null

  • 案例演示

 Queue<String> queue = new LinkedList<>();
 //添加元素:offer将元素插入到当前队列中
 queue.offer("高圆圆");
 queue.offer("佟丽娅");
 queue.offer("马哥");
 System.out.println("offer以后结果:" + queue);
 //E peek()测试:检索但不删除队列的头部元素
 System.out.println("peek头元素:" + queue.peek());
 //E element()检索但不删除当前队列的头部元素。当头部元素为null,会报异常
 System.out.println("element头元素:" + queue.element());

注意:peek()与element()方法区别:当队列为空的过程中,若使用element()方法查看头部元素时,程序将抛出 NoSuchElementException 异常,此时element方法不在适用,应该使用peek()方法查看头部元素,当队列为空时将会返回null,注意观察throws后的内容(if this queue is empty)

1.3 remove()与poll()删除元素方法

  • 方法介绍

方法名称

功能描述

E remove( )

检索和删除此队列的头

E poll( )

检索并移除此队列的头,或返回 null如果队列为空

同:容量大于0的时候,删除并返回队头被删除的元素。

异:容量为0的时候,remove()方法会抛出异常,poll()方法返回null

  • 案例演示

 Queue<String> queue = new LinkedList<>();
 //添加元素:offer将元素插入到当前队列中
 queue.offer("高圆圆");
 queue.offer("佟丽娅");
 queue.offer("马哥");
 //获取头部元素并删除
 System.out.println("poll头元素:" + queue.poll());
 System.out.println("remove头元素:" + queue.remove());

注意:poll()与remove()方法区别:当队列为空的过程中,若使用remove()方法删除头部元素时,将抛出 NoSuchElementException 异常,此时remove( )方法不在适用,应该使用poll( )方法删除头部元素,当队列为空时将会返回null,注意观察throws后的内容(if this queue is empty)

二、Deque类的简介

Deque是一个双端队列接口,继承Queue接口,Deque的实现类是LinkedList、ArrayDequeLinkedBlockingDeque,其中LinkedList是最常用的。其中LinkedBlockingDeque是一个基于链表实现的双向阻塞队列。

注意区分:LinkedBlockingQueue和LinkedBlockingDeque,两个都是队列,只不过前者只能一端出一端入,后者则可以两端同时出入,

Deque有三种用途:普通队列(一端进另一端出)、双端队列(两端都可进出)、堆栈。

  • 普通队列

Queue queue = new LinkedList()或Deque deque = new LinkedList()

  • 双端队列

Deque deque = new LinkedList()

Deque deque1 = new LinkedBlockingDeque();

LinkedBlockingDeque deque2 = new LinkedBlockingDeque();

  • 堆栈

Deque deque = new LinkedList()

实际具体用法,我下面代码有展示

1、实体类

package cn.com.easyExcel.point;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * @author: ljyang
 * @date: 2022/11/02
 **/
@Data
@NoArgsConstructor
public class PointValue implements Serializable {
    private static final long serialVersionUID = -3925356810846060856L;

    // 值
    public BigDecimal value;

    // 某时刻
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    public LocalDateTime time;

    public static PointValue of(BigDecimal value, LocalDateTime time) {
        PointValue pointPower = new PointValue();
        pointPower.setValue(value);
        pointPower.setTime(time);
        return pointPower;
    }
}

2、赋值,执行方法

package cn.com.easyExcel.point;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Deque;
import java.util.LinkedList;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * 双向队列
 *
 * @author ljyang
 * @date: 2022/11/02
 **/
@Data
@NoArgsConstructor
public class PointValueQueue implements Serializable {
    private static final long serialVersionUID = 5938295366928195243L;

    private Long pointId;

    private String pointName;

    private LinkedBlockingDeque<PointValue> queue = new LinkedBlockingDeque<PointValue>();

    public static PointValueQueue of(Long pointId, String pointName) {
        PointValueQueue pointValueQueue = new PointValueQueue();
        pointValueQueue.setPointId(pointId);
        pointValueQueue.setPointName(pointName);
        return pointValueQueue;
    }

    /**
     * 新增元素, 队尾
     *
     * @param pointValue
     */
    public void addLast(PointValue pointValue) {
        this.queue.addLast(pointValue);
    }

    /**
     * 获取队首元素值, 不移除, 队列为空时, 抛出异常
     *
     * @return
     */
    @JsonIgnore
    public PointValue getFirst() {
        return this.queue.getFirst();
    }

    /**
     * 获取队首元素值, 不移除, 队列为空时, 返回null
     *
     * @return
     */
    @JsonIgnore
    public PointValue peekFirst() {
        return this.queue.peekFirst();
    }

    /**
     * 获取队尾元素值, 不移除
     *
     * @return
     */
    @JsonIgnore
    public PointValue getLast() {
        return this.queue.getLast();
    }

    /**
     * 获取队首元素值, 移除
     *
     * @return
     */
    public PointValue poll() {
        return this.queue.poll();
    }

    /**
     * 获取队列当前大小
     *
     * @return
     */
    public int size() {
        return this.queue.size();
    }

    /**
     * 是否为空队列
     *
     * @return
     */
    @JsonIgnore
    public boolean isEmpty() {
        return this.queue.isEmpty();
    }

    /**
     * 清空
     */
    public void clear() {
        this.queue.clear();
    }

}

3、调用方法,实现过程

package cn.com.easyExcel;

import cn.com.easyExcel.point.PointValue;
import cn.com.easyExcel.point.PointValueQueue;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import org.junit.jupiter.api.Test;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @author: ljyang
 * @date: 2022/11/02
 * @description:测试写队列
 * LinkedBlockingQueue和LinkedBlockingDeque,两个都是队列,只不过前者只能一端出一端入,后者则可以两端同时出入,
 * 并且都是结构改变线程安全的队列。其实两个队列从实现思想上比较容易理解,
 * 有以下特点:
 * 链表结构(动态数组)
 * 通过ReentrantLock实现锁
 * 利用Condition实现队列的阻塞等待,唤醒
 *
 */
public class DequeDemoTest {

    @Test
    public void LinkedBlockingDeque() {
        //字符串池
        String key = StringPool.EMPTY;
        Map<Long, PointValueQueue> queueMap = getSet();
        for (int i = 0; i <20 ; i++) {
            // 队列
            PointValueQueue pointValueQueue = Optional.ofNullable(queueMap.get((long)i)).orElse(PointValueQueue.of((long)i, i+""));

            System.out.println((i)+"之前::"+pointValueQueue);
            // 队尾元素
            PointValue tail = pointValueQueue.getLast();
            // 队首元素
            PointValue head = pointValueQueue.getFirst();
            if(i%3==0){
                //pointValueQueue.clear();
                // 获取队首元素值, 移除
                pointValueQueue.poll();
                System.out.println((i)+"之后:::::"+pointValueQueue);
            }
            if(i==10){
                pointValueQueue.clear();
                System.out.println((i)+"最后:::::"+pointValueQueue);
            }
        }
    }

    //设置值
    private  Map<Long, PointValueQueue> getSet(){
        Map<Long, PointValueQueue> roomSuspectedQueue=new HashMap<Long, PointValueQueue>();
        for (int i = 0; i < 20; i++) {
            PointValueQueue pointValueQueue = PointValueQueue.of((long)i, i + "");
            for (int j = 0; j <10 ; j++) {
                LocalDateTime now = LocalDateTime.now();
                LocalDateTime time = now.plusHours(j);
                //功率
                BigDecimal p = new BigDecimal(""+j);
                // 队列新元素
                PointValue pointValue = PointValue.of(p, time);
                // 更新队列
                pointValueQueue.addLast(pointValue);
            }
            roomSuspectedQueue.put((long)i,pointValueQueue);
        }
     return roomSuspectedQueue;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值