我在使用优先级队列时遇到了一些问题。不幸的是,我的谷歌研究没有结果:(我希望有人可以帮助我。
我正在使用优先级队列通过名为“reachabilityDistance”的特定属性对某些对象进行排序,该属性是一个简单的double值。将对象插入队列可以正常工作并导致正确的排序。但后来我想轮询队列的第一个对象,即使它们的值保持不变,另一个对象的顺序也会改变。这有什么问题?
private PriorityQueue<ClusteringObject> orderedSeedQueue;
...
orderedSeedQueue = new PriorityQueue<>(clusteringObjects.size(), new ReachabilityObjectComperator());
while (!orderedSeedQueue.isEmpty()) {
clusteringObject = orderedSeedQueue.poll();
calculateNeighborhood(clusteringObject, clusteringObjects);
clusteringObject.setProcessed();
clusteringObject.setCoreDistance(minNeighbors);
resultClusterList.add(clusteringObject);
updateSeedQueue(clusteringObject.getNeighbors(), clusteringObject);
}
这是我使用优先级队列的代码片段。在updateSeedQueue方法中,在该队列中重新插入一些值(删除并再次添加)。这对我来说很好,但每次执行poll()时,所有正确的排序条目都会得到错误的顺序。
这是我的比较器:
public class ReachabilityObjectComperator implements Comparator<ClusteringObject> {
@Override
public int compare(ClusteringObject x, ClusteringObject y) {
if (x.getReachabilityDistance() < y.getReachabilityDistance()) {
return -1;
} else if(x.getReachabilityDistance() > y.getReachabilityDistance()) {
return 1;
} else {
if(x.getMetadataIndex() < y.getMetadataIndex()) {
return -1;
} else if(x.getMetadataIndex() > y.getMetadataIndex()) {
return 1;
} else {
return 0;
}
}
}
}
所以我的问题再次出现:为什么poll()会改变这个队列中剩余对象的顺序?
答案 0 :(得分:1)
PriorityQueue仅声称以正确的顺序输入第一个条目。如果您遍历PriorityQueue,您可以按任何顺序查看除第一个元素之外的所有元素,并且可以在添加/删除条目时更改。
的Javadoc方法iterator()中提供的迭代器不保证以任何特定顺序遍历优先级队列的元素。如果需要有序遍历,请考虑使用Arrays.sort(pq.toArray())。
如果您需要始终正确排序我建议使用TreeSet。
NavigableSet<MyType> orderedSeedQueue = new TreeSet<>(new MyComparator());
// add elements
while(!orderSeedQueue.isEmpty()) {
firstItem = orderSeedQueue.pollFirst();
但是,根据您的使用情况,对它们进行排序可能更简单。
List<MyType> types = ...
Collections.sort(types, new MyComparator());
for(MyType t : types) { // in sorted order