有没有一种有效的方法来确定队列项是否在“另一个”之前?

时间:2011-01-18 16:04:08

标签: java queue

对于我的Java应用程序,我需要一些方法来查明item1是否在我的队列Q中的“之前”第2项。当然,我可以使用迭代器并开始遍历列表。但是,也许还有另一种方法可以解决这个问题?

对于我的特定应用程序,我不能使用LinkedList(它提供索引并且可以很容易地确定一个对象是否在另一个之前)。

8 个答案:

答案 0 :(得分:4)

不,没有。根据定义,队列上的唯一操作是入队和出队,因此如果您的应用程序需要其他操作,那么队列就不是​​正确的结构。

答案 1 :(得分:2)

如果你只需要知道item2是否已经在队列中, 你可以使用java.util.LinkedHashMap来维护插入顺序,并且可以用作LIFO队列。

答案 2 :(得分:1)

QueueCollection,因此您始终可以将其元素复制到另一个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)

我建议引用查找表的优先级队列。这样,您可以获得要获得的元素的恒定性能,以及多项式插入成本。但是,如果您只是尝试进行比较,而不是找到最佳或最差的项目,这可能是专门用于您的用途。但是,恒定的性能总是很好。然后你不是必须迭代一个数组,而只是查找。