java队列
“队列”这个单词是英国人说的“排”。在英国“排队”的意思就是站到一排当中去。计算机科学中,队列是一种数据结构,有点类似栈,只是在队列中第一个插入的数据项也会最先被移除,而在栈中,最后插入的数据项最先移除。队列的作用就像电影院前的人们站成的排一样:第一个进入附属的人将最先到达队头买票。最后排队的人最后才能买到票。
队列和栈一样也被用作程序员的工具。它也可以用于模拟真实世界的环境,例如模拟人们在银行里排队等待,飞机等待起飞,或者因特网络上数据包等待传送。
在计算机操作系统里,有各种队列在安静地工作着。打印作业在打印队列中等待打印。当在键盘上敲击时,也有一个存储键入内容的队列。同样,如果使用文字处理程序敲击一个键,而计算机又暂时要做其它的事,敲击的内容不会丢失,它会排在队列中等待,直到文字处理程序有时间来读取它。利用队列保证了键入内容在处理时其顺序不会改变。
队列的基本操作
队列的两个基本操作是inserting(插入)一个数据项,即把一个数据项放入队尾,另一个是removing(移除)一个数据项,即移除队头的数据项。这类似于电影爱好者排队买票时先排到队尾,然后到达队头买票后离开队列。
栈中的插入和移除数据项方法的命名是很标准,称为push和pop。队列的方法至今没有标准化的命名。“插入”可以称为put、add或 enque,而“删除”可以叫delete、get或deque。插入数据项的队尾,也可以叫作back、tail或end。而移除数据项的队头,也可以叫head。下面将使用insert、remove、front和rear。
插入将值插入队尾,同时队尾箭头增加一,指向新的数据项。
数据项被移除后,同时队头指针增加一。通常实现队列时,删除的数据项还会保存在内存中,只是它不能被访问了,因为队头指针已经移到它的下一个位置了。
和栈中的情况不同,队列中的数据项不总是从数组的0下标处开始。移除了一些数据项后,队头指针会指向一个较高的下标位置。
查看操作返回队头数据项的值,然而并不从队中删除这个数据项。
要是想从空队列中移除一个数据项或想在已经满的队列中插入一个数据项,应用程序都要提示出错消息。
循环队列
当在队列中插入一个新数据项,队头的Rear箭头向上移动,移向数组下标大的位置。移除数据项时,队尾Front指针也会向上移动。这种设计可能和人们直观察觉相反,因为人们在买电影票排队时,队伍总是向前移动的,当前面的人买完票离开队伍后,其他人都向前移动。计算机中在队列里删除一个数据项后,也可以将其他数据项都向前移动,但这样做的效率很差。相反,我们通过队列中队头和队尾指针的移动保持所有数据项的位置不变。
这样设计的问题是队尾指针很快就会移到数组的末端。虽然在数组的开始部分有空的数据项单元,这是移除的数据项的位置,但是由于因为队尾指针不能再向后移动了,因此也不能再插入新的数据项,这该怎么办?
环绕式处理
为了避免队列不满却不能插入新数据项的问题,可以让队头队尾指针绕回到数组开始的位置。这就是循环队列(有时也称为“缓冲环”)。
指针回绕的过程:在队列中插入足够多的数据项,使队尾指针指向数组的未端。再删除几个数组前端的数据项。现在插入一个新的数据项。就会看到队尾指针从未端回绕到开始处的位置。新的数据项将插入这个位置。
插入更多的数据项。队尾指针如预计的那样向上移动。注意在队尾指针回绕之后, 它现在处在队头指针的下面,这就颠倒了初始的位置。这可以称为“折断的序列”:队列中的数据项存在数组两个不同的序列中。
删除足够多的数据项后,队头指针也回绕。这时队列的指针回到了初始运行时的位置状态,队头指针在队尾指针的下面。数据项也恢复为单一的连续的序列。
队列的Java代码
Queue.java程序创建了一个Queue类,它有insert()、remove()、peek()、isEmpty()和size()方法。
package 栈和队列;
class Queue{
privateint maxSize;
privatelong[] queArray;
privateint front;
privateint rear;
privateint nItems;
publicQueue(int s){
maxSize=s;
queArray=new long[maxSize];
front=0;
rear=-1;
nItems=0;
}
publicvoid insert(long j){
if(rear==maxSize-1)
rear=-1;
queArray[++rear]=j;
nItems++;
}
publiclong remove(){
long temp=queArray[front++];
if(front==maxSize)
front=0;
nItems--;
return temp;
}
publiclong peekFront(){
return queArray[front];
}
publicboolean isEmpty(){
return (nItems==0);
}
publicboolean ifFull(){
return (nItems==maxSize);
}
publicint size(){
return nItems;
}
}
程序实现的Queue类中不但有front(队头)和rear(队尾)字段,还有队列中当前数据项的个数:nItems。
Insert()方法运行的前提条件是队列不满。在Main()中没有显示这个方法,不过通常应该先调用isFull()方法并且返回false
后,才调用insert()方法。(更通用的做法是在insert()方法中加入检查队列是否满的判定,如果出现向已满队列里插入数据项的情况就抛出异常。)
一般情况,插入操作是rear(队尾指针)加一后,在队尾指针所指的位置处插入新的数据。但是,当rear指针指向数组的顶端,即 maxSize-1位置的时候,在插入数据项之前,它必须回绕到数组的底端。回绕操作把rear设置为-1,因此当rear加1后,它等于0,是数组底端的下标值,最后nItem加一。
Remove()方法运行的前提条件是队列不空,在调用这个方法之前应该调用isEmpty()方法确保队列不空,或者在remove()方法里加入这种出错检查的机制。
移除(remove)操作总是由front指针得到队头数据项的值,然后将front加一。但是,如果这样做使front的值超过数组的顶端,front就必须绕回到数组下标为0的位置上。作这种检验的同时,先将返回值临时存储起来。最后nItem减一。
Peek()方法简单易懂:它返回front指针所指数据项的值。有些队列的实现也允许查看队列队尾数据项的值;比如这些方法可称为peekFront()、peekRear()、或者只是front()和rear()。
isEmpty()、isFull()和size()方法的实现都依赖于nItems字段,它们分别返回nItems是否等于0,是否等于maxSize,或者返回它本身值。
在Queue类中包含数据项计数字段nItems会使insert()和remove()方法增加一点额外的操作,因为insert()和 remove()方法必须分别递增和递减这个变量值。这可能算不上额外的开销,但是如果处理大量的插入和移除操作,这就可能会影响性能了。
因为,一些队列的实现不使用数据项计数的字段,而是通过front和rear来计算出队列是否空或者满以及数据项的个数。如果这样做,isEmpty()、ifFull()和size()例程会相当复杂,因为就像前面讲过的那样,数据项的序列或者被折成两段,或者是连续的一段。
而且,一个奇怪的问题出现了。当队列满的时候,front和rear指针取一定的位置,但是当队列为空时,也可能呈现相同的位置关系。于是在同一时间,队列似乎可能是满的,也可能是空的。这个问题的解决方法是:让数组容量比队列数据项个数的最大值学要大一。
java队列的更多相关文章
- java队列Queue及阻塞队列
java队列 接口Queue类在java.util包,定义了以下6个方法 详细查看官方文档https://docs.oracle.com/javase/7/docs/api/java/util/Que ...
- JAVA队列的使用
JAVA队列的使用 今天跟大家来看看如何在项目中使用队列.首先我们要知道使用队列的目的是什么?一般情况下,如果是一些及时消息的处理,并且处理时间很短的情况下是不需要使用队列的,直接阻塞式的方法调用就可 ...
- Java:Java 队列的遍历
Java队列到底有没有可以遍历的功能呢?暂且试一下吧 参考链接:stl容器遍历测试 1.LinkedList实现简单遍历 for(Iter =LocTimesSerials.size()-1; iSe ...
- Java队列集合的性能测试
同时开10个线程存入和取出100万的数据,结论如下: DoubleBufferedQueue < ConcurrentLinkedQueue < ArrayBlockingQueue &l ...
- java队列——queue详细分析
Queue: 基本上,一个队列就是一个先入先出(FIFO)的数据结构 Queue接口与List.Set同一级别,都是继承了Collection接口.LinkedList实现了Deque接 口. Q ...
- Java队列学习
队列是Java集合中的重要组成部分,具有先进先出的特性,使其具有广泛的应用场景,比如排队等.因此今天就来学习一下Java中的队列.本文的例子使用的Java8环境. 继承类图 学习队列,首先要知道它的类 ...
- Java队列Queue
上个星期总结了一下synchronized相关的知识,这次将Queue相关的知识总结一下,和朋友们分享. 在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列.Java提供 ...
- Java队列——线程池创建的例子
线程池为线程生命周期开销问题和资源不足问题提供了解决方案.通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上.其好处是,因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟.这 ...
- Java队列——Disruptor 的使用
.什么是 Disruptor 从功能上来看,Disruptor 是实现了“队列”的功能,而且是一个有界队列.那么它的应用场景自然就是“生产者-消费者”模型的应用场合了. 可以拿 JDK 的 Bloc ...
随机推荐
- 给EditText的drawableRight属性的图片设置点击事件
这个方法是通用的,不仅仅适用于EditText,也适用于TextView.AutoCompleteTextView等控件. Google官方API并没有给出一个直接的方法用来设置右边图片的点击事件,所 ...
- (NO.00005)iOS实现炸弹人游戏(七):游戏数据的序列化表示
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 用plist列表文件来表示游戏数据 因为在这个炸弹人游戏中有很多 ...
- Android Studio(AS)-->导入项目
1:首先,你必须要有一个工程(Project), 才可以打开项目(Module); (注意:Eclipse中的Workspace对应Android Studio 中的Project, Eclipse中 ...
- TSVN客户端复制文件
TSVN客户端复制文件 代码重构中,可能需要将一个大文件拆分成2个小文件,同时要保证拆分后的小文件继承原来的SVN历史记录. TSVN客户端只有Rename功能,没有Copy功能. 可进入Browse ...
- JSP编译成Servlet(五)JDT Compiler编译器
通过JSP编译器编译后生成了对应的java文件,接下去要把Java文件编译成class文件.对于这部分完全没有必要重新造轮子,常见的优秀编译工具有Eclipse JDT Java编译器和Ant编译器. ...
- 敏捷测试(7)--基于story的敏捷基础知识
基于story的敏捷基础知识----迭代启动会.迭代回顾会 除需求讲解意外,需要所有团队成员参加的会议仅有两个,分别是"迭代启动会"和"迭代回顾会". (1)迭 ...
- Cannot start service MSSQL$MICROSOFT##WID on computer
在做ADFS部署过程中配置ADFS服务时遇到如下问题 检查系统日志错误日志如下,很明显"NT SERVICE\MSSQL$MICROSOFT##WID"这个账户不在log on a ...
- mac配置java环境
首先下载: 网址如下: http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk7-downloads-1880260.html 配 ...
- memcached /usr/local/memcached/bin/memcached: error while loading shared libraries: libevent-2.0.so.5: cannot open shared object file: No such file or directory
启动memcached的时候发现找不到libevent的库,这是memcache的默认查找路径不包含libevent的安装路径,所以要告诉memcached去哪里查找libevent. 操作命令如下: ...
- android自定义viewgroup初步之一----抽屉菜单
转载请注明出处 http://blog.csdn.net/wingichoy/article/details/47832151 几天前在慕课网上看到鸿洋老师的 自定义卫星菜单,感觉很有意思,于是看完视 ...