这个问题来源于StackOverFlow:
http://stackoverflow.com/questions/1846225/java-priorityqueue-with-fixed-size
为方便各位阅读,我把楼主的问题贴出来:
引用
Hi folks,
I am calculating a large number of possible resulting combinations of an algortihm. To sort this combinations I rate them with a double value und store them in PriorityQueue. Currently, there are about 200k items in that queue which is pretty much memory intesive. Acutally, I only need lets say the best 1000 or 100 of all items in the list. So I just started to ask myself if there is a way to have a priority queue with a fixed size in Java. I should behave like this: Is the item better than one of the allready stored? If yes, insert it to the according position and throw the element with the least rating away.
Does anyone have an idea? Thanks very much again!
Marco
令人大跌眼镜的Best Answer居然是:
List<Double> list = new ArrayList<Double>();
...
list.add(newOutput);
Collections.sort(list);
list = list.subList(0, 1000);
这种方法没有从根本上解决内存消耗的问题,绝对是Performence Killer。
正巧,这位朋友遇到的问题我这之前在做图像搜索时也遇到类似的问题。图片识别引擎会将匹配到的每一张图片都打上分数,越高说明相似度越大;最后输出的时候可能只需要其中的前十张就可以了。
先看一下wiki上关于优先级队列的定义:
引用
A priority queue is an abstract data type in computer programming.It is exactly like a regular queue or stack data structure, but additionally, each element is associated with a "priority".
- stack: elements are pulled in last-in first-out-order (e.g. a stack of papers)
- queue: elements are pulled in first-come first-served-order (e.g. a line in a cafeteria)
- priority queue: elements are pulled highest-priority-first (e.g. cutting in line, or VIP service).
一个标准的优先级队列至少要实现以下操作:
- insertWithPriority: add an element to the queue with an associated priority
- pullHighestPriorityElement: remove the element from the queue that has the highest priority, and return it
为Priority Queue添加指定的容量限制,就是发帖这位朋友所要的Sized Priority Queue
JDK1.6将优先级队列也加入了Collection中,但是很遗憾,没有提供Sized Priority Queue,我的实现如下:
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
public class SizedPriorityQueue<T> {
private int mSize;
private boolean mGetLowest = true;
private LinkedList<T> mList;
private LinkedList<Double> mPriorities;
private Comparator<T> mComparator;
/**
* Creates a fixed size priority queue that only tracks N values
*
* @param size - The maximum number of values to store
* @param getLowest - false means to track the highest N values,
* true means to track the lowest N values
*/
public SizedPriorityQueue(int size, boolean getLowest) {
mSize = size;
mGetLowest = getLowest;
mList = new LinkedList<T>();
mPriorities = new LinkedList<Double>();
}
/**
* Creates a fixed size priority queue with an explicit comparator for the
* class that you want to track. This can be handy if the generic class you
* have doesn't implement {@link Comparable}
*
* @param size - The maximum number of values to store
* @param getLowest - false means to track the highest N values,
* true means to track the lowest N values
* @param comparator - Explicit comparator for the classyou are tracking
*/
public SizedPriorityQueue(int size, boolean getLowest, Comparator<T> comparator) {
this(size,getLowest);
mComparator = comparator;
}
/**
* Add a value to the current list of items, it will be inserted into the
* correct position in the list if it has a higher priority than the other
* items, otherwise it will be dropped
*
* @param value
*/
public void add(T value){
if ( mComparator == null ) throw new RuntimeException("Trying to use priority queue default add without comparator defined");
int index = 0;
for ( T val : mList ){
//int comparison = val.compareTo(value);
int comparison = mComparator.compare(val,value);
if ( mGetLowest && comparison < 0 ) break;
if ( !mGetLowest && comparison > 0 ) break;
index++;
}
if ( index < mSize - 1)
mList.add(index,value);
if ( mList.size() > mSize ) mList.removeLast();
}
/**
* Add a value to the current list of items, it will be inserted into the
* correct position in the list if it has a higher priority than the other
* items, otherwise it will be dropped
*
* @param value
*/
public void add(T value, double priority){
int index = 0;
for ( double val : mPriorities ){
double comparison = priority - val;
if ( mGetLowest && comparison < 0 ) break;
if ( !mGetLowest && comparison > 0 ) break;
index++;
}
if ( index < mSize - 1) {
mList.add(index,value);
mPriorities.add(index,priority);
}
if ( mList.size() > mSize ){
mList.removeLast();
mPriorities.removeLast();
}
}
/**
* Like any ohter queue, it returns the top
* @return
*/
public T pop(){
if ( mPriorities.size() > 0 )
mPriorities.pop();
return mList.pop();
}
/**
* Just returns the top in the list, doesn't remove it
*
* @return
*/
public T poll(){
return mList.peek();
}
/**
* @return The size of current list
*/
public int size(){
return mList.size();
}
/**
* Returns an ordered list of all of the scores currently held
*
* @return
*/
public List<T> getAllScores(){
return mList;
}
public static void main(String args[]){
int numScores = 10;
int numTopScores = 5;
Random r = new Random(2);
SizedPriorityQueue<Integer> queue = new SizedPriorityQueue<Integer>(numTopScores,false);
for ( int i = 0; i < numScores; i++ ){
double score = r.nextDouble();
System.out.println("inserting score: " + score + ", number " + i);
queue.add(i,score);
}
while ( queue.size() > 0 ){
System.out.println(queue.pop());
}
}
}
我想,应该会对有如此需求的朋友带来一些帮助吧
分享到:
相关推荐
JAVA:PriorityQueue
Java优先队列(PriorityQueue)示例Java开发Java经验技巧共5页.pdf.zip
优先级队列是一种队列结构,是0个或多个元素的集合,每个元素都有一个优先权,PriorityQueue被内置于JDK中,本文就来解析Java中PriorityQueue优先级队列结构的源码及用法.
Lists_Stack_Queue_PriorityQueue.java
主要介绍了java优先队列PriorityQueue中Comparator的用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
PriorityQueue是Java中的一个优先级队列,它可以根据元素的优先级对元素进行排序,并且允许高效地获取和删除最高优先级的元素。
NULL 博文链接:https://robblog.iteye.com/blog/566114
主要介绍了Java的优先队列PriorityQueue原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
优先级队列头文件priorityqueue.h
PriorityQueue-MEX-Matlab 优先级队列 matlab
因为在Java库函数里,PriorityQueue是基于小堆建立的,所以当我们需要大堆的时候需要对它进行改建。 方法一: static class com implements Comparator { //定义一个静态内部类,继承Comparator接口,并重写他的...
前面以Java ArrayDeque为例讲解了Stack和Queue,其实还有一种特殊的队列叫做PriorityQueue,即优先队列。优先队列的作用是能保证每次取出的元素都是队列中权值小的(Java的优先队列每次取小元素,C++的优先队列...
在使用java的优先队列PriorityQueue的时候,会看到这样的用法。 PriorityQueue queue = new PriorityQueue(new Comparator(){ @Override public int compare(Integer o1, Integer o2){ return o1.compareTo(o2);...
基于任务的PriorityQueue的实现在此程序中,用户可以: 注册新任务,并传递名称和优先级 提取并返回列表中优先级最低的任务 清除任务列表 列出所有待处理的任务及其优先级 导入和导出CSV文件中的任务列表 退出该...
算法面试通关40讲完整课件 11-13 优先队列(PriorityQueue) 算法面试通关40讲完整课件 11-13 优先队列(PriorityQueue) 算法面试通关40讲完整课件 11-13 优先队列(PriorityQueue) 算法面试通关40讲完整课件 11-...
1) 掌握Java集合框架的概念以及几种具体实现:ArrayList, LinkedList, HashSet, TreeSet, PriorityQueue; 2) 掌握Java集合框架的映射的概念以及映射的两种基本实现:HashMap,TreeMap; 3)掌握枚举类型以及枚举集...
优先队列使用 O(LogN) 复杂度为测试类实现 PriorityQueue。
使用PriorityQueue 使用Deque 使用Stack 使用Iterator 使用Collections IO File对象 InputStream OutputStream Filter模式 操作Zip 读取classpath资源 序列化 Reader Writer PrintStream和...
《Java 基础核心总结》 Java 概述 什么是 Java2 Java 的特点Java 开发环境 JDK JRE Java 开发环境配置 Java 基本语法 数据类型基础语法运算符 Java 执行控制流程条件语句 if 条件语句 if...else 条件语句if...else ...
PriorityQueue 优先队列实现C# PriorityQueueLib: 基于二进制堆的最小/最大优先级队列实现PriorityQueueTests: PriorityQueue单元测试