精华内容
下载资源
问答
  • A very simple & quick question on Java libraries: is there a ready-made class that implements a Queue with a fixed maximum size - i.e. it always allows addition of elements, but it will silently r...

    A very simple & quick question on Java libraries: is there a ready-made class that implements a Queue with a fixed maximum size - i.e. it always allows addition of elements, but it will silently remove head elements to accomodate space for newly added elements.

    Of course, it's trivial to implement it manually:

    import java.util.LinkedList;

    public class LimitedQueue extends LinkedList {

    private int limit;

    public LimitedQueue(int limit) {

    this.limit = limit;

    }

    @Override

    public boolean add(E o) {

    super.add(o);

    while (size() > limit) { super.remove(); }

    return true;

    }

    }

    As far as I see, there's no standard implementation in Java stdlibs, but may be there's one in Apache Commons or something like that?

    解决方案

    Apache commons collections 4 has a CircularFifoQueue<> which is what you are looking for. Quoting the javadoc:

    CircularFifoQueue is a first-in first-out queue with a fixed size that replaces its oldest element if full.

    import java.util.Queue;

    import org.apache.commons.collections4.queue.CircularFifoQueue;

    Queue fifo = new CircularFifoQueue(2);

    fifo.add(1);

    fifo.add(2);

    fifo.add(3);

    System.out.println(fifo);

    // Observe the result:

    // [2, 3]

    If you are using an older version of the Apache commons collections (3.x), you can use the CircularFifoBuffer which is basically the same thing without generics.

    Update: updated answer following release of commons collections version 4 that supports generics.

    展开全文
  • java.util.Collection java.util.Queue add(element: E): boolean //插入一个元素到队列中 offer(element: E): boolean //插入一个元素到队列中,在大部分情况下两者是相同的,但是在有容量限制的queue中,当队列已...

    Java合集框架支持一下两种类型的容器:

    一种是为了存储一个元素合集,简称为合集(collection)

    另一种是为了存储键/值对,称为映射表(map)

    集合:

    Set用于存储一组不重复的元素

    List用于存储一个有序元素合集

    Stack用于存储采用后进先出方式处理的对象

    Queue用于存储采用先进先出方式处理的对象

    PriorityQueue用于存储按照优先级顺序处理的对象

    collection

    add(o: E): boolean //添加一个元素

    addAll(c: Collection extends E>): boolean

    clear(): void //删除所有元素

    contains(o: Object): boolean //判断合集是否包含元素o

    remove(o: Object): boolean //从该合集中移除元素o

    retainAll(c: Collection extends E>): boolean //保留同时位于c和该合集中的元素

    size(): int //返回该合集中的元素数目

    ......

    迭代器

    每个合集都是可迭代的(Iterable)。可以获得集合的Iterator对象来遍历集合中的所有元素。Iterator是一种经典的设计模式,用于在不需要暴露数据结构具体细节的情况下,来遍历一个数据结构。

    Collection接口继承自Iterable接口,Iterable接口中定义了iterator方法返回Iterator接口(迭代器),Iterator接口为遍历各种类型的合集中的元素提供了一种统一的方法。

    迭代器中remove()方法和next()一起配合使用,迭代器的初始指针指向第一个元素之前,需要先用next(),再用remove()。

    使用foreach方法其实就是对iterator方法的封装,通过反编译可以看到。

    import java.util.ArrayList;

    import java.util.Collection;

    import java.util.Iterator;

    public class TestIterator {

    public static void main(String[] args) {

    Collection collection = new ArrayList<>();

    collection.add("a");

    collection.add("b");

    collection.add("c");

    //iterator头指针指向集合头元素前面,hasNext判断有没有下一个元素,但是指针不会变

    //next方法移向下一个元素,并且返回指针移动后返回的值

    Iterator iterator = collection.iterator();

    //注意collection接口中提供的remove方法和iterator中的remove方法不能同时出现,会产生并发修改错误

    System.out.println(collection);

    //foreach反编译后其实是对iterator方法的包装

    for(String content : collection) {

    System.out.println(content);

    }

    }

    }

    线性表

    List接口继承自Collection接口,定义了一个用于顺序存储元素的合集。可以使用他的两个具体类ArrayList或者LinkedList来创建一个线性表。

    List接口定义了一个允许重复的有序合集。List接口增加了面向位置的操作,并且增加了一个能够双向遍历线性表的新线性表迭代器

    add(index: int, element: Object): boolean //在指定的索引处增加一个新的元素

    //备注:若果原来的位置有元素,那么将其及后面的所有元素索引加1

    get(intdex: int): E //返回指定索引位置的元素

    indexOf(element: Object): int //返回第一个匹配元素的索引

    listIterator(): ListIterator //返回针对该线性表元素的迭代器

    listIterator(startIndex: int): ListIterator //返回从指定为止开始的迭代器

    //此方法可以用来逆序迭代

    remove(index: int): E //移除指定索引位置处的元素

    set(intdex: int, element: Object): Object //设置指定索引处的元素

    ListIterator接口继承了Iterator接口,以增加对线性表的双向遍历能力。

    add(element: E): void //添加一个指定元素到线性表中

    hasPrevious(): boolean //逆向遍历时如果当前元素之前还有元素返回true

    next(): E //返回下一个元素

    nextIndex(): int //返回下一个元素的索引

    previous(): E //返回前一个元素

    previousIndex(): int //返回前一个元素的索引

    set(element: E): void //使用指定的元素替换previous或next方法返回的最后一个元素ArrayList用数组存储元素,这个数组是动态创建的,如果元素个数超过了数组的容量,就创建一个更大的数组,并将当前数组中所有的元素都复制到新的数组当中。LinkedList在一个链表中存储元素。

    要选用两种类中的哪一个依赖于特定的需求。如果需要下标随机访问而不会在线性表的起始位置插入或删除元素,那么ArrayList效率高,反之就用LinkedList。向ArrayList中添加元素时,其容量会自动增大。ArrayList不能自动减小,可以使用方法trimToSize()将数组容量减小到线性表的大小。

    ArrayList() //使用默认的出事容量构建一个空线性表

    ArrayList(c: Collection extends E>) //从已存在的合集中创建一个线性表

    ArrayList(initialCapacity: int) //创建一个指定初始容量的空数组线性表

    trimToSize(): void //将ArrayList实例容量裁剪到当前大小

    LinkedList()

    LinkedList(c: Collection extends E>)

    addFist(element: E):void //添加元素到线性表头部

    addLast(element: E): void //添加元素到线性表尾部

    getFirst(): E //返回该线性表第一个元素

    getLast(): E //返回该线性表最后一个元素

    removeFirst(): E //从线性表中返回并删除第一个元素

    RemoveLast(): E //从线性表中返回并删除最后一个元素

    Comparator接口

    Comparable接口定义了compareTo方法,用于比较实现了Comparable接口的同一个类的两个元素,比如String、Date、Calendar、BigInteger、BigDecimal以及所有基本类型的数字包装类。

    public intcompara(T element1,T element2)//如果element1小于element2,就返回一个负值//如果element1大于element2,就返回一个正值//若两者相等,则返回0

    向量类和栈类

    在Java API中,Vector是AbstractList的子类,Stack是Vector的子类。除了访问和修改向量的同步方法之外,Vector类与ArrayList是一样的,Vector类被广泛用在Java的遗留代码中。

    栈类Stack是作为Vector类的扩展来实现的

    java.util.Vectorjava.util.Stack

    Stack() //创建一个空的栈

    empty(): boolean //若为空则返回true

    peek(): E //返回栈顶元素

    pop(): E //返回并移除栈顶元素

    push(o: E): E //压入一个元素

    search(o: Object): int //返回指定元素的索引

    队列和优先队列

    队列(queue)是一种先进先出的数据结构。优先队列(priority queue)中,元素被赋予优先级,最高优先级的元素先被删除。

    java.util.Collection

    java.util.Queue

    add(element: E): boolean //插入一个元素到队列中

    offer(element: E): boolean //插入一个元素到队列中,在大部分情况下两者是相同的,但是在有容量限制的queue中,当队列已满时,add方法抛出错误,而offer方法返回false

    poll(): E //获取并移除队列头元素,如果空返回null

    remove(): E //获取并移除队列头元素,如果空抛出异常

    peek(): E //获取但不移除队列的头元素,如果队列为空则返回null

    element(): E //获取但不移除队列的头元素,如果为空则抛出异常

    双端队列Deque和链表LinkedList

    Deque支持在两端插入和删除元素,LinkedList类实现了Deque接口。

    PriorityQueue类实现了一个优先队列。

    总结

    Java合集框架支持集合、线性表、队列和映射表,他们分别定义在接口Set、List、Queue、Map中

    除去PriorityQueue,Java合集框架中的所有实例类都实现了Cloneable和Serializable接口。所以他们的实例都是可克隆和可实例化的。

    Comparator可以用于比较没有实现Comparable接口的类的对象。

    Vector向量类和ArrayList基本一样,不同的是Vector访问和修改向量的方法是同步的。

    展开全文
  • public class queue{private object[] data=... //队列容量private int front; //队列头,允许删除private int rear; //队列尾,允许插入//构造函数public queue(){this(10);}public queue(int initialsize){if(ini...

    public class queue{

    private object[] data=null;

    private int maxsize; //队列容量

    private int front; //队列头,允许删除

    private int rear; //队列尾,允许插入

    //构造函数

    public queue(){

    this(10);

    }

    public queue(int initialsize){

    if(initialsize >=0){

    this.maxsize = initialsize;

    data = new object[initialsize];

    front = rear =0;

    }else{

    throw new runtimeexception("初始化大小不能小于0:" + initialsize);

    }

    }

    //判空

    public boolean empty(){

    return rear==front?true:false;

    }

    //插入

    public boolean add(e e){

    if(rear== maxsize){

    throw new runtimeexception("队列已满,无法插入新的元素!");

    }else{

    data[rear++]=e;

    return true;

    }

    }

    //返回队首元素,但不删除

    public e peek(){

    if(empty()){

    throw new runtimeexception("空队列异常!");

    }else{

    return (e) data[front];

    }

    }

    //出队

    public e poll(){

    if(empty()){

    throw new runtimeexception("空队列异常!");

    }else{

    e value = (e) data[front]; //保留队列的front端的元素的值

    data[front++] = null; //释放队列的front端的元素

    return value;

    }

    }

    //队列长度

    public int length(){

    return rear-front;

    }

    }

    展开全文
  • 顺序队列 循环队列 队列(Queue)与栈都是线性存储结构,因此以常见的线性表如数组、链表作为底层的数据结构,特点: 先进先出(First In First Out)的原则,简称FIFO结构 队尾添加元素,队首删除元素 相关概念...

    顺序队列
    循环队列

    队列(Queue)与栈都是线性存储结构,因此以常见的线性表如数组、链表作为底层的数据结构,特点:

    • 先进先出(First In First Out)的原则,简称FIFO结构
    • 队尾添加元素,队首删除元素

    相关概念:

    • 队头与队尾: 允许元素插入的一端称为队尾,允许元素删除的一端称为队头
    • 入队:队列的插入操作
    • 出队:队列的删除操作
      在这里插入图片描述
      在这里插入图片描述

    顺序队列

    顺序存储上的不足:每次从数组头部删除元素(出队)后,需要将头部以后的所有元素往前移动一个位置,这是一个时间复杂度为O(n)的操作:
    在这里插入图片描述
    可能有人说,把队首标志往后移动不就不用移动元素了吗?但那样会造成数组空间的“流失”。我们希望队列的插入与删除操作都是O(1)的时间复杂度,同时不会造成数组空间的浪费,我们应该使用循环队列

    基于数组实现顺序队列 代码
    package main
    
    import (
    	"errors"
    	"fmt"
    	"os"
    )
    
    // 使用结构体管理队列
    type Queue struct {
    	Maxsize int
    	array   [5]int //数组 模拟队列
    	front   int    // 指向队列首部
    	real    int    // 指向队列 尾部
    }
    
    // 入队
    func (this *Queue) Push(val int) (err error) {
    	// 判断队列是否满
    	if this.real == this.Maxsize-1 {
    		return errors.New("queue full")
    	}
    	this.real++
    	this.array[this.real] = val
    	return
    }
    
    // 显示队列
    func (this *Queue) showQueue() {
    	for i := this.front + 1; i <= this.real; i++ {
    		fmt.Printf("%d\t", this.array[i])
    	}
    	fmt.Println()
    }
    
    // 出队
    func (this *Queue) Pop() (val int, err error) {
    
    	if this.front == this.real {
    		return val, errors.New("queue empty")
    	}
    	this.front++
    	val = this.array[this.front]
    	return
    }
    func main() {
    	queue := &Queue{
    		Maxsize: 5,
    		front:   -1,
    		real:    -1,
    	}
    	var key string
    	var val int
    	for {
    		fmt.Printf("1、输入push 入队\n2、输入pop 出队\n3、输入show 显示队列\n4、输入eixt 表示退出\n")
    		fmt.Scanln(&key)
    
    		switch key {
    		case "push":
    			fmt.Println("请输入你要入队的数据:")
    			fmt.Scanln(&val)
    			err := queue.Push(val)
    			if err != nil {
    				fmt.Println(err)
    			} else {
    				fmt.Println("入队成功")
    			}
    		case "pop":
    			val, err := queue.Pop()
    			if err != nil {
    				fmt.Println(err)
    			} else {
    				fmt.Println("出队数值",val)
    			}
    		case "show":
    			queue.showQueue()
    		case "exit":
    			os.Exit(-1)
    
    		}
    	}
    }
    
    

    循环队列

    它可以把数组看出一个首尾相连的圆环,删除元素时将队首标志往后移动,添加元素时若数组尾部已经没有空间,则考虑数组头部的空间是否空闲,如果是,则在数组头部进行插入
    在这里插入图片描述

    循坏队列的核心在队头指针和队尾指针的增加方式:

    this.tail=(this.tail+1)%this.maxsize
    this.head=(this.head+1)%this.
    

    当队列为空时this.head = this.tail,当队列为满时也有this.head = this.tail造成了判断队列是空还是满的二义性

    解决方法:
    1.增加一个参数,使删除元素为1,插入元素为0
    2.增加一个参数,记录队列的元素个数即长度
    3.空出一个单元,令(this.tail+1)%this.maxsize == this.head为队列为满的条件,以此解决二义性

    基于数组实现循坏队列 代码
    package main
    
    import (
    	"errors"
    	"fmt"
    	"os"
    )
    
    // 使用结构体管理队列
    type CycleQueue struct {
    	maxsize int
    	array   [5]int //数组
    	head    int    //队首
    	tail    int    //队尾
    }
    
    // 入队列
    func (this *CycleQueue) Push(val int) error {
    	if this.IsFull() {
    		return errors.New("queue full")
    	}
    	this.array[this.tail] = val
    	this.tail=(this.tail+1)%this.maxsize
    	return nil
    }
    
    //出队列
    func (this *CycleQueue) Pop() (val int, err error) {
    	if this.IsEmpty() {
    		return val, errors.New("queue empty")
    	}
    	val = this.array[this.head]
    	this.head=(this.head+1)%this.maxsize
    	return val, nil
    }
    
    //显示队列
    func (this *CycleQueue) ShowQ() {
    	size := this.Size()
    	if size == 0 {
    		fmt.Println("queue is empty")
    	}
    	//辅助变量 指向head
    	tempHead := this.head
    	for i := 0; i < size; i++ {
    		fmt.Println(this.array[tempHead])
    		tempHead = (tempHead + 1) % this.maxsize
    	}
    }
    
    //判断循环队列是否为空
    func (this *CycleQueue) IsEmpty() bool {
    	return this.tail == this.head
    }
    
    //判断循环队列是否满
    func (this *CycleQueue) IsFull() bool {
    	return (this.tail+1)%this.maxsize == this.head
    }
    
    //统计队列元素 个数
    func (this *CycleQueue) Size() int {
    	return (this.tail + this.maxsize - this.head) % this.maxsize
    }
    
    func main() {
    	queue := &CycleQueue{
    		maxsize: 5,
    		tail:    0,
    		head:    0,
    	}
    	var key string
    	var val int
    	for {
    		fmt.Printf("1、输入push 入队\n2、输入pop 出队\n3、输入show 显示队列\n4、输入eixt 表示退出\n")
    		fmt.Scanln(&key)
    
    		switch key {
    		case "push":
    			fmt.Println("请输入你要入队的数据:")
    			fmt.Scanln(&val)
    			err := queue.Push(val)
    			if err != nil {
    				fmt.Println(err)
    			} else {
    				fmt.Println("入队成功")
    			}
    		case "pop":
    			val, err := queue.Pop()
    			if err != nil {
    				fmt.Println(err)
    			} else {
    				fmt.Println("出队数值", val)
    			}
    		case "show":
    			queue.ShowQ()
    		case "exit":
    			os.Exit(-1)
    
    		}
    	}
    }
    
    展开全文
  • 队列也是一种特殊的线性表,它只允许在两端进行操作,插入或者取出,不允许操作中间的数据。比如只允许在对头出队,队尾入队。这样就具有先进先出的特性(first in first out-FIFO)。就像排队买东西一样,不允许插队...
  • 先看Demo: /** * 有界优先队列Demo * @author Looly * */ public class BoundedPriorityQueueDemo { public static void main(String[] args) { //初始化队列,设置队列的容量为5(只能容纳5个元素),元素类型为...
  • Cpp实现:#include #include using namespace std;struct Node{int a, b;Node() {}Node(int a, int b) : a(a), b(b) {}bool operator>(const Node& t) const{if (a > t.a) return true;...
  • /**** @ClassName: MinQ* @Description: 从小到大排列的优先队列* @author minjun* @date 2015年5月20日 上午10:01:29**/@SuppressWarnings("unchecked")public class MinQ> {// 利用数组存储队列元素private It....
  • Java 实例 - 队列(Queue)用法队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作。LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用。以下实例演示了队列...
  • Java中没有实现大顶堆或者小顶对,但是可以通过优先队列来实现。 1、小顶堆 PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, (a,b)->a-b); 2、大顶堆
  • python中的堆排序模块heapq本身不支持自定义比较函数,可以通过重写对象的__lt__方法的方式来实现自定义比较函数。 __lt__对应<,当对象之间用<比较大小的时候,就会调用__lt__方法。同样的>...
  • 实现一个拥有如下方法的线程安全有限阻塞队列: BoundedBlockingQueue(int capacity)构造方法初始化队列,其中capacity代表队列长度上限。 void enqueue(int element)在队首增加一个element. 如果队列满,调用线程...
  • 【Leetcode多线程】- Leetcode1188 设计有限的阻塞队列 实现一个拥有如下方法的线程安全有限阻塞队列: BoundedBlockingQueue(int capacity) 构造方法初始化队列,其中capacity代表队列长度上限。 void enqueue(int ...
  • 抽象队列同步器AQS应用之阻塞队列BlockingQueue详解
  • 循环队列

    2021-07-15 02:42:30
    循环队列是把顺序队列首尾相连,把存储队列元素的表从逻辑上看成一个环,成为循环队列。中文名循环队列外文名Circular Queue领域实现方式有关术语特点大小固定循环队列简介编辑语音循环队列就是将队列存储空间的最后...
  • 分布式消息队列的演进

    千次阅读 2021-10-01 00:35:17
    作者:vincentchma,腾讯 IEG 后台开发工程师一、消息队列的演进分布式消息队列中间件是是大型分布式系统中常见的中间件。消息队列主要解决应用耦合、异步消息、流量削锋等问题,具有高...
  • 队列(Queue)

    2021-02-12 15:37:37
    队列的容量可以有限,也可以是无限的。一、基于数组的Queue实现一般情况下,对于Queue而言,最核心的操作是:插入队列(enqueue)、移出队列(dequeue)。因为在队列中,插入操作是插入到队列的最后,而移出操作是移出...
  • 队列 队列是一种先进先出(First-In-First-Out,FIFO)的数据结构。可以联想一下小朋友排队打疫苗, 排在前头的先打, 排在后边的后打。打完疫苗的朋友就可以回家了(出队),刚到的朋友需要排队(入队)。 1. 实现...
  • //推动当前时刻前移 while(productor.empty()==false && productor.top().release_time==now_time) { //每个时刻 先将当前时刻的生产者队列(按照提出时间排序)任务移入 待完成任务队列 //待完成任务队列 按照最想...
  • 抽象队列同步器AQS应用之阻塞队列BlockingQueueArrayBlockingQueue 类重要属性构造器put()方法AQSawait() BlockingQueue是线程间通信的工具,在任意时刻、不管并发有多高,在单JVM上,同一时间永远都只有一个线程...
  • 阻塞队列队列阻塞队列常用阻塞队列有界阻塞 && 无界阻塞ArrayBlockingQueueLinkedBlockingQueueArray 实现和 Linked 实现地区别PriorityBlockingQueueDelayQueue实验代码:...
  • 队列

    千次阅读 2021-01-18 18:20:38
    二、队列里面要知道的概念1.出列2.入列3.空队列上例题Java/C代码 前言 没想到吧,我皮某人又回来了。 经过这么久的偷懒,哦不,沉淀,于2021年1月18号回归写博客的日子。回想那段日子,仿佛就这昨天 别bb了,快上...
  • 线性结构:有且只有一个根节点,且每个节点最多有一个直接前驱和一个直接后继的非空数据结构非线性结构:不满足线性结构的数据结构队列队列一般分为两类:链式队列和顺序队列链式队列---链式队列即用链表实现的队列...
  • FreeRTOS队列

    2021-11-24 10:24:38
    队列是为了任务与任务、任务与中断之间的通信而准备的,可以在任务与任务、任务与中断之间传递消息,队列中可以存储有限的、大小固定的数据项目。队列中能保存的最大数据项目数量叫做队列的长度。 1. 数据存储 队列...
  • 队列是为了任务与任务、任务与中断之间的通信而准备的,可以在任务与任务、任务与中断之间传递消息,队列中可以存储有限的、大小固定的数据项目。 任务与任务、任务与中断之间要交流的数据保存在队列中,叫做队列...
  • 总结 本文首先介绍了什么是补单,接着基于三方支付系统的实现完整阐述了补单机制的演进过程,最终演化为一种相对通用的异常处理模式,即基于消息队列有限状态机与多重任务兜底的业务层最终一致性保障机制,供大家...
  • 什么是队列

    2021-03-06 01:01:15
    与前面提到的数据结构相同,队列中的数据也呈线性排列。虽然与栈有些相似,但队列中添加和删除数据的操作分别是在两端进行的,就和队列这个名字一样,把它想象成排成一队的人更容易理解。在队列中,处理总是从第一名...
  • C#的循环队列

    2021-10-15 23:44:49
    // <summary> /// 循环缓存区<t> 范型 工具类 /// </summary> /// <typeparam name="T"></typeparam> public class RingBuffer<T> { public readonly int Size;... public Actio.

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 135,101
精华内容 54,040
关键字:

有限队列