队列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;
    }
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java中的队列queue)和双端队列deque)都是常用的数据结构,用于存储一系列元素并进行操作。它们在不同的场景下有不同的用途。 当我们需要在队列尾部插入元素,并从队列头部取出元素时,使用队列queue)是最好的选择。队列queue)遵循先进先出(FIFO)的原则,保证插入的元素排在最后,而取出元素时从队列头部开始。在该场景下对于Java Queue接口的实现LinkedList即可满足需求。 而在需要在队列头部和尾部同时插入删除元素时,我们可以选择双端队列deque)。双端队列deque)支持在队列头部和尾部两端插入和删除元素,并且可以使用队列和栈两种方式进行操作。JavaDeque接口即为双端队列的接口,常见实现有ArrayDeque和LinkedList。ArrayDeque由于是基于循环数组的实现,因此相比LinkedList在插入删除操作时更加高效。 因此,根据具体的需求和场景选择合适的队列或双端队列实现即可。如果只需要普通的队列功能,则使用Queue或LinkedList即可;需要更多的操作则可使用Deque或ArrayDeque。 ### 回答2: Java中的队列是一种用于存储元素的数据结构,其中存储的元素可以按照先进先出(FIFO)的顺序进行排列。Queue接口是Java集合框架中的一个接口,用于表示队列,可以实现队列的操作,如添加元素、删除元素、检索元素等。 Queue接口继承了Collection接口,该接口提供了添加元素、删除元素、以及检索队列中的元素的方法。Java中的Queue接口有两个主要的实现,即LinkedList和PriorityQueue。LinkedList实现了Queue接口,是Java中最常见的队列,而PriorityQueue实现了Queue和Comparable接口,可以用于创建优先队列。 另一个Java中的队列实现Deque(Double Ended Queue)接口。与Queue接口不同的是,Deque接口允许在队列的两端添加或删除元素,因此它支持FIFO和LIFO(后进先出)两种模式。 总之,当我们需要实现一个简单的队列时,可以考虑使用Queue接口,如果需要队列可以在两端添加或删除元素,则可以使用Deque接口。但具体使用哪个接口,还需要根据具体情况具体分析。 ### 回答3: Java队列可以使用QueueDeque两种数据结构来表示,选择使用哪种数据结构主要根据具体的业务需求和设计目的而定。 Queue是一种“先进先出”(FIFO)的队列结构,它表示一组元素的集合,其中新元素被添加到队列的尾部,而元素被提取时从队列的头部开始。Queue接口包括了add,offer,remove,poll,peek等方法。 Deque是一种“双向队列”,它实现了Queue接口并提供了高效的插入和删除操作。Deque允许在队列的两端添加或删除元素,可以被用作栈和队列双重行的结构。Deque接口包括了addFirst,addLast,offerFirst,offerLast,removeFirst,removeLast,pollFirst,pollLast,peekFirst,peekLast等方法。 如果只需要实现简单的先进先出队列的功能,使用Queue就足够了,而如果需要在队列两端进行高效的插入和删除操作,建议使用Deque。 总之,根据具体的业务需求和设计目的来选择使用Queue还是Deque

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值