对于我的Java应用程序,我需要一些方法来查明item1是否在我的队列Q中的“之前”第2项。当然,我可以使用迭代器并开始遍历列表。但是,也许还有另一种方法可以解决这个问题?
对于我的特定应用程序,我不能使用LinkedList(它提供索引并且可以很容易地确定一个对象是否在另一个之前)。
答案 0 :(得分:4)
不,没有。根据定义,队列上的唯一操作是入队和出队,因此如果您的应用程序需要其他操作,那么队列就不是正确的结构。
答案 1 :(得分:2)
如果你只需要知道item2是否已经在队列中, 你可以使用java.util.LinkedHashMap来维护插入顺序,并且可以用作LIFO队列。
答案 2 :(得分:1)
Queue
是Collection
,因此您始终可以将其元素复制到另一个Collection
,以便您检索订单,例如
List<YourType> copy = new ArrayList<YourType>(yourQueue);
if(copy.indexOf(obj1)<copy.indexOf(obj2)){
// some code here
}
当然这非常低效,但它确实有效。 (您可能必须在执行此操作时同步队列)
另一种方法是通过iterator()
:
/**
* Returns -1 if a occurs in the collection before b, 1 if b occurs before a
* and 0 otherwise.
*/
public static <T> int comparePositionInCollection(final T a,
final T b,
final Collection<T> collection){
// todo: check for a==null, b==null, a.equals(b)
final Iterator<T> iterator = collection.iterator();
boolean foundA = false;
boolean foundB = false;
int result = 0;
while(iterator.hasNext()){
final T t = iterator.next();
if(a.equals(t)){
if(foundB){
result = 1;
break;
}
foundA = true;
} else if(b.equals(t)){
if(foundA){
result = -1;
break;
}
foundB = true;
}
}
return result;
}
当然,你必须在访问迭代器之前同步队列,所以这也是非常低效的。
答案 3 :(得分:1)
我会保留一个单独的HashMap,从队列对象到整数,以及你曾经添加到队列中的对象总数的运行计数(所以当你插入对象X时,计数器意味着对象X是第N个对象插入)。每次将对象添加到队列时,将其作为键添加到HashMap;该值是计数器的当前值。
当您需要首先询问两个对象中的哪一个时,请在HashMap中查找它们并比较序数。首先是价值较低的人。
答案 4 :(得分:1)
如果快速了解订单是一个大问题,那么请考虑在您的元素中添加“订单”字段 - 并覆盖您的队列实现以填充该字段。
我不会将LinkedList'index'视为解决方案。它被实现为列表遍历。
答案 5 :(得分:0)
LinkedList是一个基本类,很难想象我可以建议作为替代方案。除了ArrayList,它支持随机访问,并且可以更快地进行索引访问。但是,ArrayList不如队列有效。
答案 6 :(得分:0)
通常,队列将提供“查看”操作,可以让您在不删除队列的情况下查看队列顶部的内容,但其他任何内容都需要不同的数据结构。或者你从队列中弹出一些东西到另一个队列,直到你搞清楚,此时你需要重新排列你弹出的值。
答案 7 :(得分:0)
我建议引用查找表的优先级队列。这样,您可以获得要获得的元素的恒定性能,以及多项式插入成本。但是,如果您只是尝试进行比较,而不是找到最佳或最差的项目,这可能是专门用于您的用途。但是,恒定的性能总是很好。然后你不是必须迭代一个数组,而只是查找。