java队列使用

本文详细介绍了Java中的队列,包括队列的种类划分,如阻塞与非阻塞、有界与无界、单向与双向链表。讲解了Queue和Deque接口的常用方法,并重点讨论了LinkedList、ArrayDeque、ConcurrentLinkedDeque等双端队列,以及PriorityQueue、ConcurrentLinkedQueue等非阻塞队列和PriorityBlockingQueue、DelayQueue、SynchronousQueue等阻塞队列的特性和使用场景。
摘要由CSDN通过智能技术生成

队列是一种特殊的线性表,遵循先入先出、后入后出的基本原则,

一般来说,它只允许在表的前端进行删除操作,而在表的后端进行插入操作,

但是java的某些队列运行在任何地方插入删除;比如我们常用的 LinkedList 集合,它实现了Queue 接口,因此,我们可以理解为 LinkedList 就是一个队列;

队列结构图

队列结构

队列种类划分

队列的种类划分可以分为三种:

  1. 是否阻塞?
  2. 有界还是无界
  3. 单向链表还是双向链表

阻塞 / 非阻塞 :

阻塞队列
  • 入列(添加元素):

    ​ 入列时, 如果元素数量超过队列总数 , 会进行等待(阻塞) , 等队列的中的元素出列后,

    ​ 元素数量未超过队列总数时,就会解除阻塞状态,进而可以继续入列;

  • 出列(读取元素):

    ​ 出列时,如果队列为空的情况下, 也会进行等待(阻塞) , 直到队列中入列了元素,即会接触阻塞状态

  • 好处 :

    ​ 可以防止队列容器溢出 , 只要满了就会阻塞等待, 也就不存在溢出的情况

非阻塞队列
  • 不管入列还是出列 , 都不会进行阻塞;

  • 出列时 , 如果元素数量超出队列总数 , 则会抛出异常;

  • 出列时 , 如果队列为空,则取出空值;

总结:
  • 只要是阻塞队列,都是线程安全的

  • 一般情况下 , 非阻塞式队列使用的比较少 , 一般都是用阻塞式的队列比较多;

  • 区分是否为阻塞队列的方法在于 看他是否有以下两个方法 :

  • 出列阻塞方法: take( )

  • 入列阻塞方法: put( )

有界/无界

有界

有界限,长度大小受限制

无界
  • 无限大小 , 说是无限大小 , 其实是有限的 , 只不过超过界限时会进行扩容;
  • 就像ArrayList一样在内部进行动态扩容

单向 / 双向链表

单向链表

每个元素中除了元素本身之外,还存储一个指针,这个指针指向下一个元素;

单向链表
双向链表

除了元素本身之外,还有两个指针,一个指针指向前一个元素的地址,另一个指针指向后一个元素的地址

双向链表

Queue(队列)接口方法:

队列提供了附加的插入提取检查操作。这些方法以两种形式存在:

  • 一种在操作失败时抛出异常,
  • 另一种返回特殊值(null或false,取决于操作)。在大多数实现中,插入操作不会失败。

增删查(抛异常)

方法名 作用
boolean add(E e) 在尾部增加一个元素,成功返回true
如果队列已满,则抛出一个IIIegaISlabEepeplian异常
E remove() 移除并返回 队列头部的元素
如果队列为空,则抛出一个NoSuchElementException异常
E element() 返回队列的头部信息,但不删除
如果队列为空,则抛出一个NoSuchElementException异常

增删查(返回特殊值)

这种插入操作形式是专门为使用容量受限的Queue实现而设计的;

方法名 作用
boolean offer(E e) 在尾部增加一个元素,成功返回true, 如果队列满了返回false
使用容量受限的队列时,这种方法通常更适合添加
E poll() 检索并删除该队列的头部,如果该队列为空,则返回null。
E peek() 检索但不删除该队列的头部,如果该队列为空,则返回null

Deque(双端队列)接口方法

支持两端元素插入和移除的线性集合。 deque这个名字是“double ended queue(双端队列)”的缩写

这个接口定义了访问deque容器两端元素的方法。

提供了插入、删除和检查元素的方法。

这些方法以两种形式存在:

  • 一种在操作失败时抛出异常
  • 另一种返回特殊值(null或false,取决于操作)

提供了对队列的头和尾操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cXhThHBg-1668410534435)(java队列.assets/image-20220714174742689.png)]

增删查(抛异常)

FirstElement (Head)
方法名 作用
boolean addFirst(e) 从头插入元素,如果没有空间,则抛出IllegalstateException异常
如果队列是有界的,最好使用offerFirst方法
E removeFirst() 返回并删除头部第一个元素 , 如果没有 , 抛出异常
E getFirst() 获取头部第一个元素 , 但是不删除 , 如果队列为空,抛出异常
LastElement (Tail)
方法名 作用
boolean addLast(e) 从尾插入元素,如果没有空间,则抛出IllegalstateException异常
如果队列是有界的,最好使用offerLast方法
E removeLast() 返回并删除尾部第一个元素 , 如果没有 , 抛出异常
E getLast() 获取尾部第一个元素 , 但是不删除 , 如果队列为空,抛出异常

增删查(返回特殊值)

这种插入操作形式是专门为 使用容量受限的Deque实现而设计的;

FirstElement (Head)
方法名 作用
boolean offerFirst(e) 从头插入一个元素 , 插入成功返回true , 插入失败返回 flase
E pollFirst() 返回并删除头部第一个元素 , 如果没有 , 返回null
E peekFirst() 获取头部第一个元素 , 但是不删除 , 如果没有 , 返回null
LastElement (Tail)
方法名 作用
boolean offerLast(e) 从尾插入一个元素 , 插入成功返回true , 插入失败返回false
E pollLast() 返回并删除尾部第一个元素 , 如果没有 , 返回null
E peekLast() 获取尾部第一个元素 , 但是不删除 , 如果没有 , 返回null

总结:

Queue:

错误处理 抛出异常 返回特殊值
入队列 add(e) offer(e)
出队列 remove( ) poll( )
队首元素 element( ) peek( )

Deque:

头插入 头插入 尾插入 尾插入
抛出异常 返回特殊值 抛出异常 返回特殊值
入队列 addFirst(e) offerFirst(e) addLast(e) offerLast(e)
出队列 removeFirst( ) pollFirst( ) removeLast( ) pollLast( )
检索元素 getFirst( ) peekFirst( ) getLast( ) peekLast( )

双端队列(Deque):

LinkedList

ArrayDeque

ConcurrentlinkedDeque

阻塞队列:

DelayQueue 延迟队列

SynchronousQueue 同步队列

PriorityBlockingQueue 优先级队列

LinkedBlockingQueue 链表阻塞队列

ArrayBlockingQueue 数组阻塞队列

队列使用

双端队列

支持两端元素插入和移除的线性集合。 deque这个名字是“double ended queue(双端队列)”的缩写

LinkedList

双向链表 , 线程不安全 , 非阻塞 , 最多可以存入一个null

public static void main(String[] args) {
   
    //创建双端队列
    Deque<Integer> deque = new LinkedList<>();
    dequeMethod(deque);
}

父类Queue的方法

 //插入
deque.add(1); 					//在末尾插入一条数据,如果满了抛出异常
deque.offer(2); 				//在末尾插入一条数据 , 成功返回true , 失败返回false

//查询
Integer element = deque.element();  //返回头部信息但不删除 , 如果队列为空,报错
Integer peek = deque.peek();        //返回头部信息但不删除 , 如果队列尾空,返回null

//删除
Integer remove = deque.remove();  //返回并删除头部的数据 如果队列为空,报错
Integer poll = deque.poll();     //返回并删除 , 如果队列尾空 返回null

抛出异常的方法

//插入
deque.addFirst(1);   				//从头插入一个元素 , 如果没有空间 抛出异常
deque.addLast(2);    				//从尾插入一个元素 , 如果没有空间 抛出异常

//查询
Integer first = deque.getFirst();    //获取头部第一个元素 , 但是不删除 , 如果队列为空,抛出异常
Integer last = deque.getLast();      //获取尾部第一个元素 , 但是不删除 , 如果队列为空,抛出异常

//删除
Integer integer = deque.removeFirst();  //返回并删除头部第一个元素 , 如果没有 , 抛出异常
Integer integer1 = deque.removeLast();  //返回并删除尾部第一个元素 , 如果没有 , 抛出异常

返回特殊值的方法

//插入
deque.offerFirst(1);    			   //从头插入一个元素 , 插入成功返回true , 插入失败返回 flase
deque.offerLast(2);     			   //从尾插入一个元素 , 插入成功返回true , 插入失败返回false

//查询
Integer integer2 = deque.peekFirst();   //获取头部第一个元素 , 但是不删除 , 如果没有 , 返回null
Integer integer3 = deque.peekLast();    //获取尾部第一个元素 , 但是不删除 , 如果没有 , 返回null

//删除
Integer integer4 = deque.pollFirst
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值