java优先队列
来源:互联网 发布:java是什么意思 编辑:程序博客网 时间:2024/06/08 11:59
我们知道队列是遵循先进先出(First-In-First-Out)模式的,但有些时候需要在队列中基于优先级处理对象。举个例子,比方说我们有一个每日交易时段生成股票报告的应用程序,需要处理大量数据并且花费很多处理时间。客户向这个应用程序发送请求时,实际上就进入了队列。我们需要首先处理优先客户再处理普通用户。在这种情况下,Java的PriorityQueue(优先队列)会很有帮助。
PriorityQueue类在Java1.5中引入并作为 Java Collections Framework 的一部分。PriorityQueue是基于优先堆的一个无界队列,这个优先队列中的元素可以默认自然排序或者通过提供的Comparator(比较器)在队列实例化的时排序。
优先队列不允许空值,而且不支持non-comparable(不可比较)的对象,比如用户自定义的类。优先队列要求使用Java Comparable和Comparator接口给对象排序,并且在排序时会按照优先级处理其中的元素。
优先队列的头是基于自然排序或者Comparator排序的最小元素。如果有多个对象拥有同样的排序,那么就可能随机地取其中任意一个。当我们获取队列时,返回队列的头对象。
优先队列的大小是不受限制的,但在创建时可以指定初始大小。当我们向优先队列增加元素的时候,队列大小会自动增加。
PriorityQueue是非线程安全的,所以Java提供了PriorityBlockingQueue(实现BlockingQueue接口)用于Java多线程环境。
我们有一个用户类Customer,它没有提供任何类型的排序。当我们用它建立优先队列时,应该为其提供一个比较器对象。
Customer.java
packagecom.journaldev.collections; publicclass Customer { privateint id; privateString name; publicCustomer(inti, String n){ this.id=i; this.name=n; } publicint getId() { returnid; } publicString getName() { returnname; } }
我们使用Java随机数生成随机用户对象。对于自然排序,我们使用Integer对象,这也是一个封装过的Java对象。
下面是最终的测试代码,展示如何使用PriorityQueue:
PriorityQueueExample.java
packagecom.journaldev.collections; importjava.util.Comparator;importjava.util.PriorityQueue;importjava.util.Queue;importjava.util.Random; publicclass PriorityQueueExample { publicstatic void main(String[] args) { //优先队列自然排序示例 Queue<Integer> integerPriorityQueue = newPriorityQueue<>(7); Random rand = newRandom(); for(inti=0;i<7;i++){ integerPriorityQueue.add(newInteger(rand.nextInt(100))); } for(inti=0;i<7;i++){ Integer in = integerPriorityQueue.poll(); System.out.println("Processing Integer:"+in); } //优先队列使用示例 Queue<Customer> customerPriorityQueue = newPriorityQueue<>(7, idComparator); addDataToQueue(customerPriorityQueue); pollDataFromQueue(customerPriorityQueue); } //匿名Comparator实现 publicstatic Comparator<Customer> idComparator = newComparator<Customer>(){ @Override publicint compare(Customer c1, Customer c2) { return(int) (c1.getId() - c2.getId()); } }; //用于往队列增加数据的通用方法 privatestatic void addDataToQueue(Queue<Customer> customerPriorityQueue) { Random rand = newRandom(); for(inti=0; i<7; i++){ intid = rand.nextInt(100); customerPriorityQueue.add(newCustomer(id, "Pankaj "+id)); } } //用于从队列取数据的通用方法 privatestatic void pollDataFromQueue(Queue<Customer> customerPriorityQueue) { while(true){ Customer cust = customerPriorityQueue.poll(); if(cust == null)break; System.out.println("Processing Customer with ID="+cust.getId()); } } }
注意我用实现了Comparator接口的Java匿名类,并且实现了基于id的比较器。
当我运行以上测试程序时,我得到以下输出:
Processing Integer:9Processing Integer:16Processing Integer:18Processing Integer:25Processing Integer:33Processing Integer:75Processing Integer:77Processing Customer with ID=6Processing Customer with ID=20Processing Customer with ID=24Processing Customer with ID=28Processing Customer with ID=29Processing Customer with ID=82Processing Customer with ID=96
从输出结果可以清楚的看到,最小的元素在队列的头部因而最先被取出。如果不实现Comparator,在建立customerPriorityQueue时会抛出ClassCastException。
Exceptioninthread "main"java.lang.ClassCastException: com.journaldev.collections.Customer cannot be cast to java.lang.Comparable at java.util.PriorityQueue.siftUpComparable(PriorityQueue.java:633) at java.util.PriorityQueue.siftUp(PriorityQueue.java:629) at java.util.PriorityQueue.offer(PriorityQueue.java:329) at java.util.PriorityQueue.add(PriorityQueue.java:306) at com.journaldev.collections.PriorityQueueExample.addDataToQueue(PriorityQueueExample.java:45) at com.journaldev.collections.PriorityQueueExample.main(PriorityQueueExample
译文链接: http://www.importnew.com/6932.html
转载自:http://www.importnew.com/6932.html
- JAVA队列之优先队列
- JAVA队列之优先队列
- java优先队列
- java PriorityQueue优先队列
- java优先队列 PriorityQueue
- [java]优先队列
- 【Java】优先队列PriorityQueue
- Java优先队列
- JAVA优先队列
- 优先队列 java PriorityQueue
- Java数据结构----优先队列
- (java)优先队列
- Java 优先队列
- Java中的优先队列
- java优先队列
- 优先队列java-PriorityQueue
- Java优先队列初识
- java API------PriorityQueue优先队列
- ButtenKinfe(8.5.1)简单运用
- 微信小程序项目总结:for循环,绑定点击事件,二维数组列表渲染 ...
- javascript 有意思的事 全局变量 局部变量
- 动态标题栏
- hdu1253胜利大逃亡(bfs)
- java优先队列
- 查看文档创建日期、修改日期和文档大小
- 微信、支付宝App支付-JPay 简单而不简洁的App支付SDK
- ubuntu下安装程序报错:Could not get lock /var/lib/dpkg/lock解决
- IntelliJ IDEA 之 HelloWorld 项目创建及相关配置文件介绍
- List按照多个字段进行排序
- 获取对象的当前状态
- ElasticSearch的 Query DSL 和 Filter DSL
- SpringMVC——接收请求参数和页面传参