javaQueue集合-BlockingQueue-Deque集合

Queue集合

Queue集合继承自Collection接口,它的常用实现类是LinkedList 和 PriorityQueue 。
Queue用来存放等待处理元素的集合,这种场景一般用来进行缓冲、并发访问。

Queue特有方法

方法名说明
添加操作
Boolean add(E e)
Boolean offer(E e )
在尾部添加,实现类禁止添加null元素
添加失败,会报运行时错误NullPointerException
添加失败,不会崩溃,返回false
删除操作
E remove()
E poll()
删除头部并返回头部
队列为空,报NoSuchElementException错
队列为空,返回null
查询操作
E element()
E peek()
获取但不删除
队列为空,报错
队列为空,返回null
判断是否含有某元素
Boolean contain(E e)
判断队列中是否包含某个元素

注意:

  • 大多数实现Queue接口的实现类都具有禁止添加null元素的功能,避免在查询时返回null,比如ArrayBlockingQueue,PriorityBlockQueue;但是还有一些实现类没有实现这样的功能,比如LinkedList。
  • 虽然LinkedList没有明确禁止添加null元素,但是Queue的实现类都不允许添加null元素,原因是:poll、peek方法在异常(对队列为空)的时候会返回null,当添加null元素后,会产生歧义(不知道是发生异常还是获取到null元素)

PriorityQueue

概念

队列的核心思想是先进先出,优先级队列有点不一样。
优先级队列中,数据按关键词有序排列,插入新数据的时候,会自动插入到合适的位置保证队列的有序性。(有序:升序或降序)
PriorityQueue是基于优先堆的一个无界队列,队列中的元素排序:默认的自然排序(使用Comparable接口)或比较器排序(使用Comparator接口)。

方法

都是Queue中的方法。add、offer、remove、poll、get、element、peek。
具体方法讲解

  • 添加元素 add()/offer()
        System.out.println(que.add(null));
        // 添加null元素,会报NullPointerException
        System.out.println(que.offer(null));
        // 添加null元素,则会报NullPointerException
        System.out.println(que.add(100));
        System.out.println(que.add(10));
        System.out.println(que.add(30));
        System.out.println(que.add(20));
        System.out.println(que);//输出[10, 20,30,100]
  • 获取元素 element()/peek()
        System.out.println(que.element());//10
        System.out.println(que.peek());//10
        // 获取元素 默认情况下 每次获取的元素是列表头部元素
        System.out.println(que);//[10, 20, 30, 100]
  • 删除元素 remove()/poll()
 System.out.println(que.remove());//10
        System.out.println(que.poll());//20
        // 依次删除头部元素
        System.out.println(que);//[30, 100]
  • 判断元素是否存在 contain(E e)
System.out.println(que.contains(30));//true
  • 整体代码:
public class QueueDEmo {
    public static void main(String[] args) {
        Queue<Integer> que = new PriorityQueue<Integer>();

//        System.out.println(que.add(null));
        // 添加null元素,会报NullPointerException
//        System.out.println(que.offer(null));
        // 添加null元素,则会报NullPointerException
        System.out.println(que.add(100));
        System.out.println(que.add(10));
        System.out.println(que.add(30));
        System.out.println(que.add(20));
        System.out.println(que);//输出[10, 20,30,100]

        System.out.println("------------");
        System.out.println(que.element());//10
        System.out.println(que.peek());//10
        // 获取元素 默认情况下 每次获取的元素是列表头部元素
        System.out.println(que);

        System.out.println("----------");
        System.out.println(que.remove());//10
        System.out.println(que.poll());//20
        // 依次删除头部元素
        System.out.println(que);//30 ,100


    }
}
案例

案例1
需求:在未排序的数组中,找到第K个未排序的最大值。
解题思路:

思路1:冒泡排序
外层循环控制比较的轮次,for(int i =0;i<array.length;i++)
	内层循环控制每轮比较次数 for(int j = i ;j<array.length;j++)
	当i++ == k的时候退出循环。
思路2Queue优先级队列实现
// 方法传入参数int[] array,int k
pubilc void method(int[] array,int k){
	//创建PriorityQueue队列
	PriorityQueue<Integer> queue = new PriorityQueue<Integer>();
	// 使用增强for循环(数据类型 变量名:数组名)
	for(Integer ini : array){
		// 使用队列.add(变量名),给队列添加元素
		array.add(ini);
	}
	// 判断队列元素>k,则删除队列元素 队列.poll()
	while(true){
		if(queue.size() > k ) queue.poll();
		else break;
	}
	// 最后返回值是 队列.peek()
	return queue.peek();

代码:冒泡排序

// 330-Test1
public class Test1 {
    // 需求:在未排序的数组中,找到第K个未排序的最大值。
    public static int findKthLargest(int[] array, int K){
        int result = array[0];
        int tep = 0;
        // 使用冒泡排序
        // 外层循环表示程序 比较轮数
        for(int i = 0;i <array.length;i++){
            // 内层循环表示 每轮比较次数
            for(int j = i+1; j<array.length;j++ ){
                if(array[i] > array[j]){
                    tep = array[i];
                    array[i] = array[j];
                    array[j] = tep;
                }
            }
            if(i++ == K){
                result = array[array.length-K];
                break;
            }
        }
        return result;
    }

    public static void main(String[] args) {
        int[] array = {10,9,5,24,35};
        int result = findKthLargest(array,3);
        System.out.println(result);
    }
}

代码:优先级队列PriorityQueue

    // 优先级队列实现
    public static int findKthLargestQueue(int[] array,int k){
        Queue<Integer> que = new PriorityQueue<Integer>();
        for(int arr:array){
            que.add(arr);
        }
        while(true){
        	 if(que.size() > k) que.poll();
        	 else break;
       	 }
        return que.peek();
    }

BlockingQueue阻塞队列

概念

  • BlockingQueue是一个接口 public interface BlockingQueue extends Queue< E >
  • 阻塞队列与普通队列的区别:
    当队列是空的,获取元素的操作将会阻塞;
    当队列是满的,添加元素的操作会被阻塞。
  • 是java.util.concurrent包提供的接口,常用于多线程编程中容纳任务队列。
  • 使用阻塞队列的好处:不需要关心什么时候阻塞线程、什么时候唤醒线程,阻塞队列都帮我们考虑了。

底层原理?

阻塞队列底层是通过AQS,抽象队列同步器实现的;
AQS具备 线程阻塞等待机制和被唤醒时锁分配机制,这些机制是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中,队列是双向队列。
具体AQS抽象队列同步器是通过ReentrantLock可重入锁实现的;

常用实现类

类名说明
ArrayBlockingQueue数组结构组成的有界阻塞队列
LinkedBlockingQueue链表结构组成的有界阻塞队列
LinkedTransferQueue链表结构组成的无界阻塞队列,和SynchronousQueue类似,还含有非阻塞方式
LinkedBlockingDeque链表结构组成的双向阻塞队列
SynchronousQueue不存储元素的阻塞队列,即直接提交给线程不保持它们 = 单个元素的队列
PriorityBlockingQueue支持优先级排序的无界阻塞队列
DelayQueue使用优先级队列实现的延迟无界阻塞队列

常用方法

方法类型抛出异常特殊值阻塞超时
插入add(e)
阻塞队列满,再插入元素抛出IllegalStateException:Queue full…
offer(e)
成功返回true,失败返回false
put(e)
阻塞队列满,生产线程持续执行put操作,队列会阻塞生产线程直到put数据成功或响应中断退出
offer(e,time,unit) 阻塞队列满,队列会阻塞生产线程一定时间,超时后生产线程会退出
移除remove()
阻塞队列为空,执行remove操作会抛出NoSuchElementException
poll()
成功返回队列元素,队列没有则返回null
take()
阻塞队列为空,消费者线程从队列里take元素,队列会一直阻塞消费者线程直到队列可用
poll(long timeout , TimeUnit unit)
当队列为空,队列会阻塞消费者线程一段时间,超过时限后消费者线程退出
检查element()
阻塞队列为空,执行element会抛出NoSuchElementException异常
peek()
返回队列的第一个元素
不可用不可用

LinkedBlockingQueue

  • 使用LinkedBlockingQueue< E > 实现线程同步。
    LinkedBlockingQueue< E > 是一个基于已连接节点的,范围任意的阻塞队列。
    该队列按照先进先出的原则排序元素。
    队列的头部是在队列中时间最长的元素,队列的尾部是在队列中时间最短的元素,新元素插入到队列的尾部。
    获取队列元素的操作只会获取头部元素,如果队列满了或者为空会进入阻塞状态。
  • 常用方法:
方法名说明
LinkedBlockingQueue()创建一个容量为Integer.MAX_VALIE的LinkedBlockingQueue
put( E e )在队尾添加一个元素,如果队列满则阻塞当前线程,直到队列有空位
size()返回列表中的元素个数
take()移除并返回头部元素,如果队列空则阻塞当前线程,直到取到元素为止

正则化表达式

参考
https://www.jb51.net/article/245515.htm

Deque

概述

Deque接口,实现双端队列,两头都允许出队和入队;
public interface Deque< E > extends Queue< E >

构造方法及实现类

ArrayDeque、ConcurrentLinkedDeque、LinkedBlockingDeque、LinkedList

常用方法

方法名说明来源
Boolean isEmpty()此集合中不包含元素,返回trueCollection接口
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值