熟悉队列的使用——滑动窗口的最大值

队列的使用:一般情况下,如果是对一些及时消息的处理,并且处理时间很短的情况下是不需要队列的,直接阻塞式的方法调用就可以了。但是如果在消息处理的时候特别费时间,这个时候如果有新消息来了,就只能处于阻塞状态,造成用户等待。这个时候便需要引入队列了。当接收到消息后,先把消息房贷队列中,然后再用行的线程进行处理,这个时候就不会有消息阻塞了。
个人认为消息队列的主要特点是异步处理,主要目的是减少请求响应时间和解耦。所以主要的使用场景就是将比较耗时而且不需要即时(同步)返回结果的操作作为消息放入消息队列。同时由于使用了消息队列,只要保证消息格式不变,消息的发送方和接收方并不需要彼此联系,也不需要受对方的影响,即解耦和。
Queue的实现

1、没有实现的阻塞接口的LinkedList: 实现了java.util.Queue接口和java.util.AbstractQueue接口
  内置的不阻塞队列: PriorityQueue 和 ConcurrentLinkedQueue
  PriorityQueue 和 ConcurrentLinkedQueue 类在 Collection Framework 中加入两个具体集合实现。
  PriorityQueue 类实质上维护了一个有序列表。加入到 Queue 中的元素根据它们的天然排序(通过其 java.util.Comparable 实现)或者根据传递给构造函数的 java.util.Comparator 实现来定位。
  ConcurrentLinkedQueue 是基于链接节点的、线程安全的队列。并发访问不需要同步。因为它在队列的尾部添加元素并从头部删除它们,所以只要不需要知道队列的大 小,       ConcurrentLinkedQueue 对公共集合的共享访问就可以工作得很好。收集关于队列大小的信息会很慢,需要遍历队列。

2)实现阻塞接口的:
  java.util.concurrent 中加入了 BlockingQueue 接口和五个阻塞队列类。它实质上就是一种带有一点扭曲的 FIFO 数据结构。不是立即从队列中添加或者删除元素,线程执行操作阻塞,直到有空间或者元素可用。
五个队列所提供的各有不同:
  * ArrayBlockingQueue :一个由数组支持的有界队列。
  * LinkedBlockingQueue :一个由链接节点支持的可选有界队列。
  * PriorityBlockingQueue :一个由优先级堆支持的无界优先级队列。
  * DelayQueue :一个由优先级堆支持的、基于时间的调度队列。
  * SynchronousQueue :一个利用 BlockingQueue 接口的简单聚集(rendezvous)机制。

例题:给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
窗口大于数组长度的时候,返回空。


package Linkedlist;

import java.util.*;

public class Solution {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        String[] nums = str.split(",");
        int[] num = new int[nums.length];
        for (int i = 0; i < nums.length; i++) {
            num[i] = Integer.parseInt(nums[i]);
        }
        int windowSize = sc.nextInt();
            System.out.println(maxInWindows(num, windowSize));
    }

    public static ArrayList<Integer> maxInWindows(int[] num, int size) {

        ArrayList<Integer> arrayList = new ArrayList<>();
        if(size>num.length){
            return arrayList;
        }
        //Queue<Integer> queue = new LinkedList<>();//LinkedList实现了queue
        //Queue<Integer> queue = new PriorityQueue<>();//插入的数据会被排序,从小到大排列
        PriorityQueue<Integer> queue = new PriorityQueue<>((o1, o2) -> o2 - o1); //大顶堆
        int max = 0;
        for (int i = 0; i < num.length - size+1; i++) {
            for (int j = i; j < i + size; j++) {
                queue.offer(num[j]);
            }
//            while(queue!=null && queue.size()!= 0) {
//                int temp;
//                temp = queue.poll();
//                max = Math.max(max, temp);
//                //  queue.poll();
//            }
//            if(max != 0&& max != num.length){
//                arrayList.add(max);
            arrayList.add(queue.peek());
//            }
//            max = 0;
            queue.clear();
        }
            return arrayList;
    }
}

数据结构拓展:

一、队列

Queue<Integer> queue = new LinkedList<>();//声明队列
queue.add(1);//添加数据
queue.offer(1);//添加数据
//add() offer()都是想队尾插入数据 区别是add()方法插入数据超出队列界限时候会抛出异常,而offer()方法是返回false
queue.poll();//输出队列
queue.peek();//输出队列但不删除
queue.remove();//输出队列
//在队列元素为空的情况下,remove() 方法会抛出NoSuchElementException异常,poll() 方法只会返回 null 
Queue<Integer> queString = new PriorityQueue<>();//插入的数据会被排序,小顶堆
PriorityQueue<Integer> queue = new PriorityQueue<>((o1, o2) -> o2 - o1); //大顶堆

二、栈

Stack stack1 = new Stack();
Stack<String> stackString = new Stack<>();
stackString.pop();//输出元素,栈为空的时候会抛出异常
stackString.add();//添加元素
stackString.push();//添加元素
//add是继承自Vector的方法,且返回值类型是boolean。
//push是Stack自身的方法,返回值类型是参数类类型

三、Hashmap

Map<String,String> map = new HashMap();//创建map
for(Map.Entry<String,String> entry : map.entrySet()){
	System.out.println(entry.getValue());
	System.out.println(entry.getKey());
}
//Map.Entry 是Map中的一个接口,他的用途是表示一个映射项(里面有Key和Value)
//Map.entrySet() 这个方法返回的是一个Set<Map.Entry<K,V>>表示一个映射项的Set。
//Map.Entry里有相应的getKey和getValue方法,即JavaBean,让我们能够从一个项中取出Key和Value。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值